Addition-chain exponentiation: Difference between revisions

Content added Content deleted
(→‎{{header|C}}: add comparison to binary chains)
(Deleted J implementation as there's another one now and this was non-optimal and only sometimes better than binary chain)
Line 178: Line 178:
93 9 10
93 9 10
...</lang>
...</lang>

=={{header|J}}==

<lang j>vars=: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
mul=: '+/ .*'
eq=: '=:'
b2e=:3 :0 NB. express binary chain as equation
(|.x{.~##:y) b2e y
:
b=. }.#: y
v=. (-#b) {. x
({.x),eq,(,(mul,~])"0 |.b#v), ([,eq,])/(],mul,])"0 v
)

addch=:3 :0
p=. q: y
N=: +/n=. #@#:"0 p
assert N <: 1+#vars NB. enough variables?
v=. (|.N{.vars) <@(' ',])/.~ (+/\n) I. 1+i.N
3}.;v b2e&.> p
)</lang>

This implementation finds an expression which calculates the given exponent. <code>b2e</code> finds the binary chain expression for that exponent. <code>addch</code> finds the addition chain expression.

This implementation of addch uses binary chain for each prime factor of the exponent and combines them.

Example use:

<lang j> mul=: '*'
addch 15
C*C*C =:A*B*B=:A*A
addch 31415
L*M*M=:L*L =:G*I*J*K*K*K=:J*J=:I*I=:H*H=:G*G =:A*B*C*F*F*F=:E*E=:D*D=:C*C=:B*B=:A*A
addch 27182
N*N =:A*B*C*E*I*K*M*M*M=:L*L=:K*K=:J*J=:I*I=:H*H=:G*G=:F*F=:E*E=:D*D=:C*C=:B*B=:A*A
addch 27182*31415
a*a =:Y*Z*Z=:Y*Y =:T*V*W*X*X*X=:W*W=:V*V=:U*U=:T*T =:N*O*P*S*S*S=:R*R=:Q*Q=:P*P=:O*O=:N*N =:A*B*C*E*I*K*M*M*M=:L*L=:K*K=:J*J=:I*I=:H*H=:G*G=:F*F=:E*E=:D*D=:C*C=:B*B=:A*A</lang>

I tried to compute the expression given by addch 31415 using matrix multiplication as my multiplier, and using

<lang j>A=: ".;._2]0 :0
4 _3 4r3 _1r4
_13r3 19r4 _7r3 11r24
3r2 _2 7r6 _1r4
_1r6 1r4 _1r6 1r24
)</lang>

However, I ran out of memory needed to represent the arbitrary precision intermediate results.

When I use floating point values instead of arbitrary precision, the result I got was:

<lang j> mul=: +/ .*
do addch 31415
_ __ _ __
__ _ __ _
_ __ _ __
__ _ __ _</lang>

Here a single underline represents floating point infinity and a double underline represents negative floating point infinity.

So I have elected to not try to compute the other requested results.

That said, note that this approach exceeds the values given in the A003313 by 1 in 22 cases, when considering the first 100 values in the sequence.