3
$\begingroup$

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?

$\endgroup$
2
  • $\begingroup$ 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. $\endgroup$
    – Szabolcs
    Mar 29 '17 at 16:52
  • 3
    $\begingroup$ 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. $\endgroup$
    – Szabolcs
    Mar 29 '17 at 16:54
4
$\begingroup$

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.

$\endgroup$
5
  • $\begingroup$ Hello, I got weird results if the power is -1. Is there a way to fix it? I.e. CForm[a*p^-1] works fine but CForm[p^-1] does not. $\endgroup$ Mar 26 '19 at 12:54
  • $\begingroup$ @VsevolodA. see update $\endgroup$
    – Carl Woll
    Mar 26 '19 at 15:03
  • $\begingroup$ Thanks. Though now it's not working for negative powers (it previously worked fine): the only problem was with the -1 power expression when there are no constants around like p^-1. $\endgroup$ Mar 26 '19 at 16:23
  • $\begingroup$ @VsevolodA. Do you have an example where it doesn't work for negative powers? It works for me. $\endgroup$
    – Carl Woll
    Mar 26 '19 at 16:28
  • $\begingroup$ Sure, CForm[1*p^-2] $\endgroup$ Mar 26 '19 at 16:34
3
$\begingroup$

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

$\endgroup$
1
  • $\begingroup$ 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] = . $\endgroup$ May 11 '20 at 20:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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