简体   繁体   中英

Fibonacci in O log(N) with different seeds

This code is a translation from pseudo-code in a mathemathics wiki to resolve Fibonacci problem in O log(n).

The problem comes when you want to change the seeds of fibonacci (1,0), this is most mathematical question and complexity question than programatically...

So... Where to put A and B to start for example with seeds 5,6?

Thanks for your time!

public static BigInteger Fib(int A, int B, int n)
        {
            if (n <= 0)
                return 0;

            n = n - 1;
            _auxOne = 0;
            _auxTwo = 1;

            Matrix[0, 0] = _auxTwo; //a
            Matrix[0, 1] = _auxOne; //b
            Matrix[1, 0] = _auxOne; //c
            Matrix[1, 1] = _auxTwo + _auxOne; //d

            while (n > 0)
            {
                if (n % 2 != 0)
                {
                    _auxOne = Matrix[1, 1] * Matrix[0, 1] + Matrix[1, 0] * Matrix[0, 0]; //(db+ca)
                    _auxTwo = Matrix[1, 1] * (Matrix[0, 1] + Matrix[0, 0]) + Matrix[1, 0] * Matrix[0, 1]; //(d(b+a)+cb)
                    Matrix[0, 0] = _auxOne;
                    Matrix[0, 1] = _auxTwo;
                }
                _auxOne = BigInteger.Pow(Matrix[1, 0], 2) + BigInteger.Pow(Matrix[1, 1], 2); //(c²+d²)
                _auxTwo = Matrix[1, 1] * (2 * Matrix[1, 0] + Matrix[1, 1]); //(d*(2c+d))
                Matrix[1, 0] = _auxOne;
                Matrix[1, 1] = _auxTwo;

                n = n / 2;
            }
            return Matrix[0, 0] + Matrix[0, 1];
        }

Ok, as i wrote before in comments, actually we just need "normal" Fibonacci matrix to multiply to our modified matrix with seed, so one part of my code is mutation of existing OP code. I made only 2 changes - i need whole matrix instead of calculation result and replaced BigInteger with Int64 to avoid additional references.

public static Int64 PerversationFib(int A, int B, int n) 
{
    if (n <= 0)
        return 0;

    if (n == 1)
        return A + B;
    else 
    {
        Int64[,] myMatrix = new Int64[2, 2] { { A , B }, { B, A+B} };
        Int64[,] fibMatrix = Fib(n);

        //a11·b11 + a12·b21
        return myMatrix[0, 0] * fibMatrix[0, 0] + myMatrix[0, 1] * fibMatrix[1, 0];  

    }

}

public static Int64[,] Fib( int n)
{
    if (n <= 0)
        return null;

    //n = n - 1;
   Int64 _auxOne = 0, _auxTwo = 1;
   Int64[,] Matrix = new Int64[2, 2]; 

   Matrix[0, 0] = _auxTwo; //a
   Matrix[0, 1] = _auxOne; //b
   Matrix[1, 0] = _auxOne; //c
   Matrix[1, 1] = _auxTwo + _auxOne; //d


    while (n > 0)
    {
        if (n % 2 != 0)
        {
            _auxOne = Matrix[1, 1] * Matrix[0, 1] + Matrix[1, 0] * Matrix[0, 0]; //(db+ca)
            _auxTwo = Matrix[1, 1] * (Matrix[0, 1] + Matrix[0, 0]) + Matrix[1, 0] * Matrix[0, 1]; //(d(b+a)+cb)
            Matrix[0, 0] = _auxOne;
            Matrix[0, 1] = _auxTwo;
        }
        _auxOne = Matrix[1, 0] * Matrix[1, 0]  +Matrix[1, 1]*Matrix[1,1]; //(c²+d²)
        _auxTwo = Matrix[1, 1] * (2 * Matrix[1, 0] + Matrix[1, 1]); //(d*(2c+d))
        Matrix[1, 0] = _auxOne;
        Matrix[1, 1] = _auxTwo;

        n = n / 2;
    }
    Matrix[1, 0] = Matrix[0, 1];
    Matrix[1, 1] = Matrix[0, 0]+Matrix[0,1] ;
    return Matrix;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM