3

Is there a simple way to make Mathematica write CForm[p^2] not as Power[p,2] but rather as p*p and so on for other much more complicated expressions?

Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263
Physics_maths
  • 1,329
  • 1
  • 10
  • 26
  • I think the best way is to try to make use of the SymbolicC package. See here. I am always struggling when trying to extend CForm to behave better. – Szabolcs Mar 29 '17 at 16:52
  • 3
    One more suggestion: if you are dealing with polynomials, you can consider putting them into HornerForm for more efficient evaluation. And a shameless plug: if you evaluate many integer powers in C++ (not in C), you may be interested in my blog post on the topic. In fact you might want to generate power<n>(x) with a small extension to SymbolicC. – Szabolcs Mar 29 '17 at 16:54

2 Answers2

4

You can override the default CForm handling of Power as follows:

Unprotect[Power];
Format[Power[a_,n_Integer?Positive], CForm] := Distribute[
    ConstantArray[Hold[a],n],
    Hold, List, HoldForm, Times
]
Protect[Power];

Example:

CForm[p^3]

(* p*p*p *)

The only downside is that I don't know how to control parenthesization, so that:

CForm[x^2 y^3]

(* x*x*(y*y*y) *)

unnecessarily parenthesizes y*y*y.

Carl Woll
  • 130,679
  • 6
  • 243
  • 355
3

If the symbol you are using is known in advance, you can useTagSetDelayed and associate an UpValue with that symbol inside the Powerfunction:

p /: Power[p, 2] := HoldForm[p*p]

Then

CForm[p^2]

p*p

Stitch
  • 4,205
  • 1
  • 12
  • 28
  • This works BUT seems to break things -- Solve stopped working right, and I got strange results in some calculations. If you do this, I'd suggest doing it right before you use CForm, and then right afterwards undo it by doing p /: Power[p,2] = . – Dan Sandberg May 11 '20 at 20:19