views:

562

answers:

3

Is there a practical algorithm that gives "multiplication chains"

To clarify, the goal is to produce a multiplication change of an arbitrary and exact length
Multiplication chains of length 1 are trivial.

A "multiplication chain" would be defined as 2 numbers, {start} and {multiplier}, used in code:

 Given a pointer to array of size [{count}]   // count is a parameter
 a = start;
 do 
 {
      a = a * multiplier;  // Really: a = (a * multiplier) MOD (power of 2
      *(pointer++) = a;   
 }
 while (a != {constant} )
 // Postcondition:  all {count} entries are filled.

I'd like to find a routine that takes three parameters
1. Power of 2
2. Stopping {constant}
3. {count} - Number of times the loop will iterate

The routine would return {start} and {multiplier}.

Ideally, a {Constant} value of 0 should be valid.

Trivial example:

power of 2 = 256  
stopping constant = 7
number of times for the loop = 1  
returns {7,1}

Nontrivial example:

power of 2 = 256  
stopping constant = 1
number of times for the loop = 49
returns {25, 19}

The maximum {count} for a given power of 2 can be fairly small.
For example, 2^4 (16) seems to be limited to a count of 4

+1  A: 

Why wouldn't this satisfy the requirements?

start = constant;
multiplier = 1;

Update: I see now that the number of loops is one of the input parameters. It sounds like this problem is a special case of, or at least related to, the discrete logarithm problem.

Greg Hewgill
Errr...yes. So probably the 'start' should be a fourth parameter to the routine (assuming the purpose of the number of steps is clarified).
Jonathan Leffler
Yes, this is the trivial case, where number of loops is 1. Number of loops is a parameter to the calculation algorithm.
Procedural Throwback
+5  A: 

You are asking for nontrivial solutions to the following modular equation:

s * m^N = C (mod 2^D)

where

  • s is the starting constant
  • m is the multiplier
  • N is the number of iterations (given by the problem)
  • C is the final constant (given by the problem)
  • D is the exponent of the power of 2 (given by the problem)

Have a look at Euler's theorem in number theory.

For an arbitrary odd m (which is prime with 2^D), you have

m^phi(2^D) = 1 (mod 2^D)

thus

C * m^phi(2^D) = C (mod 2^D)

and finally

C * m^(phi(2^D)-N) * m^N = C (mod 2^D)

Take

s = C * m^(phi(2^D)-N)

and you're done. The Euler's phi function of a power of 2 is half that power of 2, i.e.:

phi(2^D) = 2^(D-1)

Example. Let

  • N = 5
  • C = 3
  • 2^D = 16
  • phi(16) = 8

Choose arbitrarily m = 7 (odd), and compute

3 * 7^(8-5) = 1029
s = 1029 mod 16 = 5

Now

s * m^N = 5 * 7^5 = 84035
84035 mod 16 = 3 == C
Federico Ramponi
With an odd m, I can't reach 0 - which makes sense now that I see the equation. With even 'm', it will reach 0 eventually. Is there a different form of an equation to get a constant of 0.
Procedural Throwback
if C is 0 then you can choose s = C*... = 0 (this is again a trivial solution...)
Federico Ramponi
How so? C = 0, N=13, 2^D = 256Start = 0 wouldn't satisfy N=13
Procedural Throwback
Note that my answer provides s, m such that *after exactly* N iterations you reach C. But you could reach C also in *less* than N iterations, i.e. you could loop several times between a sequence of numbers x, y, z, C, x, y, z, C...
Federico Ramponi
Can this be changed to give the first "C" (since that would be the terminating condition of the while loop) ?
Procedural Throwback
Perhaps with some more number theory you can compute explicitly a m such that the loop requires *exactly* N steps (not less) to reach the final constant.
Federico Ramponi
Any thoughts on where to start looking for that piece, and how might I rephrase the question?
Procedural Throwback
Procedural Throwback
+2  A: 

Here is a method for computing the values for start and multiplier for the case when constant is odd:

  1. Find such odd m (m = multiplier) that order of m modulo 2^D is at least count, meaning that smallest n such that m^n = 1 (mod 2^D) is at least count. I don't know any other way to find such m than to make a random guess, but from a little experimenting it seems that half of odd numbers between 1 and 2^D have order 2^(D-2) which is maximal. (I tried for D at most 12.)

  2. Compute x such that x * m^count = 1 (mod 2^D) and set start = x * constant (mod 2^D).

Such x can be found with "extended euclidean algorithm": Given a and b with no common divisor, it gives you x and y such that a * x + b * y = 1. Here a=m^count mod 2^D and b = 2^D.

edit: If constant happens to be even, you can divide it with a power of 2, say 2^k, to make in odd, then do the above for input {constant/2^k, count, 2^(D-k)} and finally return {start*2^k,multiplier}.

mattiast
Really nice - I had seen the cycles of 2^(D-2), but didn't take things further.For even 'c', there are cycles of up to 2^(D-3), shouldn't something similar work?
Procedural Throwback
Now that should do it for cases where c isn't zero.
mattiast
That makes sense, and that explains why the cycle lengths for some even #'s were so much shorter, since I need to hunt in the 2^(D-k) range.
Procedural Throwback
With odd multipliers (relatively prime to 2^D), odd starting points give the maximum cycle length, even starting points are shorter but still never hit 0.So that leaves the even multipliers to get to 0, with only the length remaining?
Procedural Throwback
I see, for even dividers, the power of 2 determines the count, not quite sure how to get the intermediate value yet.What's with those "other" odd multipliers that don't form a cycle - Shouldn't any relatively prime pair form a cycle?
Procedural Throwback
If constant is zero, you need D >= count. In that case you can choose multiplier=2 and start=2^(D-count)
mattiast
For C = 0, I have D - (low order 0 bits of start and nultiplier) as the count. Above the first 1 bit, the rest seems arbitrary.
Procedural Throwback
For step 1, it looks like there is a better way than guessing, although I cant understand why.. The first 2 m values are always 3,5. -3/-5 mod 2^D are also full. Starting from 3 or 5, every other power works?
Procedural Throwback