2
$\begingroup$

I have many of the following expressions which I want to convert using CForm:

 24612842763116842319872/(5042560366642267*x - 256*(2446745837411900 + 4901398098088043*y - 144207654645973248*z));

Another example for testing:

-((524288 (29427736469514379027531261659072347+58899562724319710108573382000184640 y-1732944474195510410991057714955859184 z))/(5042560366642267 x-256 (2446745837411900+4901398098088043 y-144207654645973248 z))^2)

What is the regular expression rule to use in Mathematica in order to convert all the long integers in the output of CForm into the product of their prime factors:

RegularExpression["regex"]

My thoughts are, first extract every long integer, and FactorInteger them to obtain all prime factors; then replace the original long integers with product of their prime factors.

The target final expression should be usable immediately in C/C++.

But I have no idea how to use the regular expression rule.

$\endgroup$
  • 2
    $\begingroup$ Hint: don't use regular expressions. $\endgroup$ – Oleksandr R. Nov 28 '13 at 9:16
  • $\begingroup$ Your second example is not proper MMA syntax. Pleas post the expresion before applying CForm. $\endgroup$ – Kuba Nov 28 '13 at 11:40
  • $\begingroup$ hi @Kuba , it is a "fraction" form as: -((524288 (29427736469514379027531261659072347+58899562724319710108573382000184640 y-1732944474195510410991057714955859184 z))/(5042560366642267 x-256 (2446745837411900+4901398098088043 y-144207654645973248 z))^2) $\endgroup$ – LCFactorization Nov 28 '13 at 11:44
  • $\begingroup$ So after converting into CForm, it is : (-524288*(29427736469514379027531261659072347 + 58899562724319710108573382000184640*y - 1732944474195510410991057714955859184*z))/ Power(5042560366642267*x - 256*(2446745837411900 + 4901398098088043*y - 144207654645973248*z),2) $\endgroup$ – LCFactorization Nov 28 '13 at 11:45
  • 1
    $\begingroup$ FWIW, some of your numbers are too big to fit into 64 bits (e.g. Log[2., 24612842763116842319872] is 74.3818) $\endgroup$ – Daniel Chisholm Nov 28 '13 at 13:27
5
$\begingroup$
expr = -((524288 (29427736469514379027531261659072347 + 
    58899562724319710108573382000184640 y - 
    1732944474195510410991057714955859184 z))/(5042560366642267 x - 256 
    (2446745837411900 + 4901398098088043 y - 144207654645973248 z))^2)

with Powers, general approach

ClearAll@f;
f[expr_] := Replace[
    CForm[expr],
    i_Integer /; And[! PrimeQ[i], Abs[i] > 1000] :> (
           Sign[i] (Times @@ (If[#2 == 1, HoldForm @ #, HoldForm[Power[##]]
                                ] & @@@ FactorInteger[Abs@i])))
    , \[Infinity]]

f[expr]
-(((-(z*(Power(2,4)*3*13*31*3616032431023*24774565539206567657)) + y*(Power(2,6)*5*23*8002657978847786699534426902199) + 
     1949*15098889927919127258866732508503)*Power(2,19))/
 Power(x*(7*137*389*50651*266867) - 256*(4901398098088043*y - z*(Power(2,8)*Power(3,2)*11*5690011625867) + 
      Power(2,2)*Power(5,2)*24467458374119),2))
$\endgroup$
  • $\begingroup$ thank you! It is very impressive. How to you handle expression like this: (-524288*(29427736469514379027531261659072347 + 58899562724319710108573382000184640*y - 1732944474195510410991057714955859184*z))/ Power(5042560366642267*x - 256*(2446745837411900 + 4901398098088043*y - 144207654645973248*z),2) $\endgroup$ – LCFactorization Nov 28 '13 at 11:08
  • 1
    $\begingroup$ @LCFactorization take a look at the more general approach, but do not put CFrom expresions into f, only regular ones. $\endgroup$ – Kuba Nov 28 '13 at 11:56
4
$\begingroup$

Here's an idea (without RegExps):

We set up a function fact that extracts the prime factors and wrap them in some head, here we use factors:

fact = factors @@ Flatten[ConstantArray @@@ FactorInteger[#]] &;

(I use ConstantArray to show all factors)

Then we apply this to the expression and replace all integers of absolute value larger than some number:

expr = 24612842763116842319872/(5042560366642267*x - 256*(2446745837411900 + 4901398098088043*y - 144207654645973248*z));
n = 10^6;
expr /. x_Integer /; Abs[x] > n :> fact@x

and find:

factors[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 41, 683, 15277, 13717003]/(x factors[7, 137, 389, 50651, 266867] - 256 (y factors[4901398098088043] + factors[2, 2, 5, 5, 24467458374119] + z factors[-1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 11, 5690011625867]))

$\endgroup$
  • $\begingroup$ Thank you! How to obtain desired final expression (if there are many ) from the current step? $\endgroup$ – LCFactorization Nov 28 '13 at 11:13
  • 1
    $\begingroup$ @LCFactorization: please define what you'd like to obtain in the final step (this is not fully clear to me). Thanks $\endgroup$ – Pinguin Dirk Nov 28 '13 at 11:28
  • $\begingroup$ I now think combine both yours and @Kuba's can get the desired results. The desired final expression should be able to be used immediately as C/C++ expression. For example, the factors[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 41, 683, 15277, 13717003] better be Power(2,22)*41*683*15277*13717003, and so on. Thank you; very good idea without using regular expr $\endgroup$ – LCFactorization Nov 28 '13 at 11:34
  • 1
    $\begingroup$ ah ok, I wasn't aware of that syntax, my bad. You could modify fact accordingly. Let me know if you need any help & thanks for the feedback $\endgroup$ – Pinguin Dirk Nov 28 '13 at 12:17
  • $\begingroup$ Thank you for kind reply! I am new; all these are useful for me to learn MMA. $\endgroup$ – LCFactorization Nov 28 '13 at 12:36
2
$\begingroup$

Here's an alternate approach where I teach CForm how to format integers in the way you desire:

Unprotect[Integer];

Format[i_Integer?CompositeQ, CForm] /; Abs[i]>1000 := Replace[
    Apply[HoldForm @* Times] @ FactorInteger[i],
    {
    {n_, 1} :> n,
    {n_, m_} :> Power[n, m]
    },
    {2}
]

Protect[Integer];

Here's your examples:

CForm[
    24612842763116842319872/(5042560366642267*x - 256*(2446745837411900 + 4901398098088043*y - 144207654645973248*z))
]

(Power(2,22)*41*683*15277*13717003)/ (7*137*389*50651*266867*x - 256*(Power(2,2)*Power(5,2)*24467458374119 + 4901398098088043*y - Power(2,8)*Power(3,2)*11*5690011625867*z))

CForm[
    -((524288 (29427736469514379027531261659072347+58899562724319710108573382000184640 y-1732944474195510410991057714955859184 z))/(5042560366642267 x-256 (2446745837411900+4901398098088043 y-144207654645973248 z))^2)
]

(-Power(2,19)*(1949*15098889927919127258866732508503 + Power(2,6)*5*23*8002657978847786699534426902199*y - Power(2,4)*3*13*31*3616032431023*24774565539206567657*z))/ Power(7*137*389*50651*266867*x - 256*(Power(2,2)*Power(5,2)*24467458374119 + 4901398098088043*y - Power(2,8)*Power(3,2)*11*5690011625867*z),2)

$\endgroup$

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.