LongInt Algorithm::Modular_exponentiation(LongInt a,LongInt m, LongInt r)
{
    //qDebug()<<"algorithm.cpp: Modular_exponentiation"<<a<<m<<r;
    if(r==0)
    {
        //qDebug()<<"algorithm.cpp: Modular_exponentiation :( 1 )";
        return LongInt(1);
    }
    QVector<LongInt> part;
    part<<1;
    LongInt a_k(1),k(1);

    while(1)
    {
        //qDebug()<<a_k<<a<<m;
        a_k=((a_k*a)%m);
        part<<a_k;
        if(part.last()==1)
        {
            part.removeLast();
            //qDebug()<<"algorithm.cpp: Modular_exponentiation :"<<part.value( ((r % LongInt(part.length()))).toInt());
            return part.value( ((r % LongInt(part.length()))).toInt());
        }
        k+=1;
        if(k>r)
        {
            //qDebug()<<"algorithm.cpp: Modular_exponentiation :"<<part.value( ((r % LongInt(part.length()))).toInt());
            return part.value( ((r % LongInt(part.length()))).toInt());
            return a_k;
        }
    }
}
LongInt Algorithm::Random(LongInt inf,LongInt sup)// random є [inf;sup]
{
    if(inf==sup)
    {
        return sup;
    }
    if(inf>sup)
    {
        return -LongInt(0);
    }
    LongInt _a;
    _a=LongInt(std::rand());
    _a<<=10;
    //_a/=LongInt(RAND_MAX+1);
    _a=( _a % (sup-inf+1))+inf;
    //qDebug()<<inf<<"<="<<_a<<"<="<<sup;
    return _a;
}
Exemple #3
0
Number* Rational::round(){
    Number* res;
    Rational* one_two = new Rational(ONE,LongInt(2));
    if(sgn()>=0)//正数
        res = this->add(one_two)->floor();
    else
        res = this->sub(one_two)->ceiling();
    delete one_two;
    return res;
}
APPROXMVBB_EXPORT void samplePointsGrid(Matrix3Dyn & newPoints,
                      const MatrixBase<Derived> & points,
                      const unsigned int nPoints,
                      OOBB & oobb) {


    if(nPoints >= points.cols() || nPoints < 2) {
        ApproxMVBB_ERRORMSG("Wrong arguements!")
    }

    newPoints.resize(3,nPoints);

    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<unsigned int> dis(0, points.cols()-1);

    //total points = bottomPoints=gridSize^2  + topPoints=gridSize^2
    unsigned int gridSize = std::max( static_cast<unsigned int>( std::sqrt( static_cast<double>(nPoints) / 2.0 )) , 1U );

    // Set z-Axis to longest dimension
    //std::cout << oobb.m_minPoint.transpose() << std::endl;
    oobb.setZAxisLongest();

    unsigned int halfSampleSize = gridSize*gridSize;
    std::vector< std::pair<unsigned int , PREC > > topPoints(halfSampleSize,    std::pair<unsigned int,PREC>{} );    // grid of indices of the top points (indexed from 1 )
    std::vector< std::pair<unsigned int , PREC > > bottomPoints(halfSampleSize, std::pair<unsigned int,PREC>{} ); // grid of indices of the bottom points (indexed from 1 )

    using LongInt = long long int;
    MyMatrix<LongInt>::Array2 idx; // Normalized P
    //std::cout << oobb.extent() << std::endl;
    //std::cout << oobb.m_minPoint.transpose() << std::endl;
    Array2 dxdyInv =  Array2(gridSize,gridSize) / oobb.extent().head<2>(); // in K Frame;
    Vector3 K_p;

    Matrix33 A_KI(oobb.m_q_KI.matrix().transpose());

    // Register points in grid
    auto size = points.cols();
    for(unsigned int i=0; i<size; ++i) {

        K_p = A_KI * points.col(i);
        // get x index in grid
        idx = (  (K_p - oobb.m_minPoint).head<2>().array() * dxdyInv ).template cast<LongInt>();
        // map to grid
        idx(0) = std::max(   std::min( LongInt(gridSize-1), idx(0)),  0LL   );
        idx(1) = std::max(   std::min( LongInt(gridSize-1), idx(1)),  0LL   );
        //std::cout << idx.transpose() << std::endl;
        unsigned int pos = idx(0) + idx(1)*gridSize;

        // Register points in grid
        // if z axis of p is > topPoints[pos]  -> set new top point at pos
        // if z axis of p is < bottom[pos]     -> set new bottom point at pos

        if( topPoints[pos].first == 0) {
            topPoints[pos].first  = bottomPoints[pos].first  = i+1;
            topPoints[pos].second = bottomPoints[pos].second = K_p(2);
        } else {
            if( topPoints[pos].second < K_p(2) ) {
                topPoints[pos].first = i+1;
                topPoints[pos].second = K_p(2);
            }
            if( bottomPoints[pos].second > K_p(2) ) {
                bottomPoints[pos].first = i+1;
                bottomPoints[pos].second = K_p(2);
            }
        }
    }

    // Copy top and bottom points
    unsigned int k=0;

    // k does not overflow -> 2* halfSampleSize = 2*gridSize*gridSize <= nPoints;
    for(unsigned int i=0; i<halfSampleSize; ++i) {
        if( topPoints[i].first != 0 ) {
            // comment in if you want the points top points of the grid
//            Array3 a(i % gridSize,i/gridSize,oobb.m_maxPoint(2)-oobb.m_minPoint(2));
//            a.head<2>()*=dxdyInv.inverse();
            newPoints.col(k++) =  points.col(topPoints[i].first-1);  //  A_KI.transpose()*(oobb.m_minPoint + a.matrix()).eval() ;
            if(topPoints[i].first != bottomPoints[i].first) {
                // comment in if you want the bottom points of the grid
//                Array3 a(i % gridSize,i/gridSize,0);
//                a.head<2>()*=dxdyInv.inverse();
                newPoints.col(k++) = points.col(bottomPoints[i].first-1); //  A_KI.transpose()*(oobb.m_minPoint + a.matrix()).eval() ;
            }
        }
    }
    // Add random points!
    while( k < nPoints) {
        newPoints.col(k++) = points.col( dis(gen) ); //= Vector3(0,0,0);//
    }
}
 bool operator == (const int &n) const {
     return *this == LongInt(n);
 }
bool Algorithm::Agrawal_Kayal_Saxena(LongInt a)
{
    LongInt log_2_a=0;
    LongInt _a=a;
    LongInt r(2),k;
    while( _a >=2)
    {
        _a/=2;
        log_2_a += 1;
    }
    //+++++++++++++++1+++++++++++++++
    LongInt a_=a,midle;
    _a=1;
    for(k=2;k <= log_2_a;k+=1)
    {
        _a=0;
        a_=a-1;
        while(1)
        {
            r=(a_+_a)/2;
            midle=(r)^k;
            if(midle==a)
            {
                //qDebug()<<"algorithm.cpp:"<<a<<"="<<r<<"^"<<k;
                return false;
            }
            if(midle>a)  a_=r;
            if(midle<a)  _a=r;
            if((a_-_a)<=1) break;
        }
    }
    //
    //+++++++++++++++2+++++++++++++++
    LongInt sqr_log_2=log_2_a*log_2_a;
    //LongInt maxr=log_2_a^5;
    bool nextR=true;
    for(r=2;nextR/*&&r<maxr*/;r+=1)
    {
        nextR=false;
        _a=1;
        //qDebug()<<"\nr="<<r;
        for(k=1;(!nextR)&&k<=sqr_log_2;k+=1)
        {
            _a=((_a*a) % r);
            //qDebug()<<"algorithm.cpp:Agrawal_Kayal_Saxena"<<k<<_a;
            nextR=(_a==1||_a==0);
        }
    }
    r-=1;
    //qDebug()<<"r="<<r;
    //+++++++++++++++3+++++++++++++++
    for(_a=r;_a>LongInt(1);_a-=1)
    {
        k=HCD(_a,a);
        //qDebug()<<_a;
        if(k==a)
        {
            break;
        }
        if(k>1)
        {
            return false;
        }
    }
    //+++++++++++++++4+++++++++++++++
    if(a<=r)
    {
        return true;
    }
    //
    //+++++++++++++++5+++++++++++++++
    k=2;
    r=LongInt::Sqrt(Eulers_totient(r))*log_2_a;
    //qDebug()<<"Sqrt(Eulers_totient(r))*log_2_a="<<r;
    for(;k<=r;k+=1)
    {
        if(Modular_exponentiation(k,a,a)!=k)
        {
            //qDebug()<<"Modular_exponentiation("<<k<<","<<a<<","<<a<<")=\n"<<Modular_exponentiation(k,a,a);
            return false;
        }

    }
    //+++++++++++++++6+++++++++++++++

    return true;
}
LongInt Algorithm::Modular_Multiplicative_Inverse(LongInt a, LongInt mod, bool* is_inverse_norm)
{
    //qDebug()<<"algorithm.cpp: Inverse-"<<a<<mod;
    if(a==0)
    {
        qDebug()<<qA<<"Inverse a==0";
        return a;
    }
    if(a<LongInt(0))
    {
        a+=mod;
    }
    if(a>=mod)
    {
        a=a%mod;
    }
    //
    LongInt t;
    LongInt an_2=0,an_1=1;
    LongInt invert;

    LongInt b=a;
        a=mod;

    while(b!=1&&b!=0)
    {
        //qDebug()<<an_2<<an_1;
        //qDebug()<<"a b:"<<a<<b;
        an_2=an_2-an_1*(a/b);
        invert=an_1;
        an_1=an_2;
        an_2=invert;
        //==========algorithm=HCD(a,b)============
        t=b;
        b=a%b;
        a=t;
        //========================================
    }
    if(b==0&&a!=mod&&a!=1)
    {
        qDebug()<<"algorithm.cpp:Modular_Multiplicative_Inverse: HCD(a,mod)="<<a;
        qDebug()<<"Inverse number for a does not exist";
        if(is_inverse_norm!=NULL)
        {
            (*is_inverse_norm)=false;
        }
        return a;
    }
    //
    if(an_1<LongInt(0))
    {
        //qDebug()<<"algorithm.cpp: inverse="<<an_1+mod;
        return mod+an_1;
    }
    if(is_inverse_norm!=NULL)
    {
        (*is_inverse_norm)=true;
    }
    //qDebug()<<"algorithm.cpp: inverse="<<an_1;
    return an_1;
}
LongInt Algorithm::Toom_Cook(LongInt a, LongInt b)
{
    /*/
    a=LongInt("529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450");
    b=LongInt("29834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450");
    qDebug()<<a.length();
    LongInt z=Strassen(a,b);
    /*/
    //===T1===========initialization=table=and=stack===
    qDebug()<<"Hello Lord of Iteration";
    QStack<LongInt> U,V;
    QStack<LongInt> W;
    QStack<int> C;

    int Index,i,j;//for iteration;
    //=======================Table===========
    int k=1;
    int Q=2,R=1;
    Table table={4,2};

    QVector<Table> qv_table;
    qv_table<<table<<table;
    QVector<Table>::iterator iter_table;//=qv_table.begin();

    int last_q=4;

    qDebug()<<qA<<"\"(0)\""<<Q<<R<<table.q<<table.r;
    while(a.length()>(qv_table.last().q+last_q))
    {
        qDebug()<<"algorithm.cpp:"<<"("+QString::number(k)+")"<<Q<<R<<table.q<<table.r;
        k++;
        Q+=R;
        table.q*=table.r;
        R++;
        if(R*R<=Q)//if((R+1)^2>=Q) R++;
        {
            table.r*=2;
        }
        else R--;
        last_q=qv_table.last().q;
        qv_table<<table;
    }
    qDebug()<<"algorithm.cpp:"<<"("+QString::number(k)+")"<<Q<<R<<table.q<<table.r;
    iter_table=qv_table.end();
    iter_table--;
    LongInt numbers[10*iter_table->r+1];
    //===================T2============================
    C.push(-1);
    C<<a.number<<-5<<b.number;
    a.clear();
    b.clear();
    int forSwitch=1;//iter_table--;
    //====================Cycle========================
    //bool isEnd=0;
    while(1)
    {
        switch(forSwitch)
        {
        case 1://T3
        {
            k--;
            iter_table--;
            //qDebug()<<"K="<<k;
            if(!k)
            {
                a.clear();
                b.clear();
                //qDebug()<<"C="<<C;
                while(!C.isEmpty())
                {
                    Q=C.pop();
                    if(Q>=0)
                    {
                        b.push_front(Q);
                    }
                    else
                    {
                        break;
                    }
                }
                //qDebug()<<"C="<<C;
                while(!C.isEmpty())
                {
                    Q=C.pop();
                    if(Q>=0)
                    {
                        a.push_front(Q);
                    }
                    else
                    {
                        C.push(Q);
                        break;
                    }
                }
                //qDebug()<<"algorithm.cpp:"<<a<<"*"<<b<<"=";
                forSwitch=5;
                a*=b;
                //qDebug()<<"algorithm.cpp:"<<a;
            }
            else
            {
                forSwitch=2;
            }
            break;
        }
        case 2://T4 T5
        {
            //=====T4=========
            Index=0;
            numbers[0].clear();
            //qDebug()<<"T4 C"<<C;

            while(!C.isEmpty())
            {
                Q=C.pop();
                if(Q>=0)
                {
                    if(numbers[Index].length()>=iter_table->q)
                    {
                        //qDebug()<<"algorithm.cpp:("<<Index<<")"<<numbers[Index];
                        numbers[Index].normalization();
                        Index++;
                        numbers[Index].clear();
                    }
                    numbers[Index].push_front(Q);
                }
                else
                {
                    break;
                }
            }
            //qDebug()<<"algorithm.cpp:("<<Index<<")"<<numbers[Index];
            R=iter_table->r+Index;
            //qDebug()<<R;
            //qDebug()<<Index;
            for(j=0;j<=R;j++)
            {
                a=numbers[Index];
                for(i=Index-1;i>=0;i--)
                {
                    a*=j;
                    a+=numbers[i];
                }
                U<<a;
            }
            Index=0;
            numbers[0].clear();
            while(!C.isEmpty())
            {
                Q=C.pop();
                if(Q>=0)
                {
                    if(numbers[Index].length()>=iter_table->q)
                    {
                        //qDebug()<<"algorithm.cpp:("<<Index<<")"<<numbers[Index];
                        numbers[Index].normalization();
                        Index++;
                        numbers[Index].clear();
                    }
                    numbers[Index].push_front(Q);
                }
                else
                {
                    C.push(Q);
                    break;
                }
            }
            //qDebug()<<"algorithm.cpp:("<<Index<<")"<<numbers[Index];
            //qDebug()<<Index;
            for(j=0;j<=R;j++)
            {
                a=numbers[Index];
                //qDebug()<<"algorithm.cpp:j="<<j;
                for(i=Index-1;i>=0;i--)
                {
                    a*=j;
                    a+=numbers[i];
                }
                //qDebug()<<"algorithm.cpp:a="<<a;
                V<<a;
            }
            //qDebug()<<"algorithm.cpp:V="<<V;
            //=====T5=========
            if(!U.isEmpty()||!V.isEmpty())
            {
                C<<-2<<V.pop().number<<-5<<U.pop().number;
                while(!U.isEmpty()||!V.isEmpty())
                {
                    C<<-3<<V.pop().number<<-5<<U.pop().number;
                }
            }
            else
            {
                //qDebug()<<"Error algorithm.cpp: U or V Empty";
            }
            //qDebug()<<"C="<<C;
            b.clear();
            b.push_front(-4);
            W<<b;
            forSwitch=1;
            break;
        }
        case 3://T6
        {
            W<<a;
            forSwitch=1;
            //qDebug()<<"algorithm.cpp:a="<<a;
            break;
        }
        case 4://T7 T8 T9
        {
            //qDebug()<<W<<"\n";
            //W.clear();
            //W<<-4<<10<<304<<1980<<7084<<18526;
            Index=-1;
            while (!W.isEmpty())
            {
                //b=W.pop();
                Index++;
                //qDebug()<<"W="<<W;
                numbers[Index]=W.pop();
                //qDebug()<<W.length();
                if(numbers[Index]<0)
                {
                    //qDebug()<<W.length();
                    Index--;
                    break;
                }
            }
            //qDebug()<<W;
            //=====T7=========
            for(j=1;j<=Index;j++)
            {
                for(i=0;i<=Index-j;i++)
                {
                    numbers[i]=(numbers[i]-numbers[i+1])/LongInt(j);
                    //qDebug()<<"numb"<<numbers[i]<<j;
                }
                //qDebug()<<numbers[Index-j+1]<<j;
            }
            //qDebug()<<numbers[Index-j+1];

            /*/
            for(i=0;i<=Index;i++)
            {
                qDebug()<<"(T7)numbers="<<numbers[i];
            }
            /*/

            //=====T8=========
            //qDebug()<<"";
            for(j=Index-1;j>=1;j--)
            {
                for(i=Index-j;i>=1;i--)
                {
                    //qDebug()<<j<<i;
                    numbers[i]-=numbers[i-1]*j;
                }
            }

            /*/
            for(i=0;i<=Index;i++)
            {
                qDebug()<<"(T8)numbers="<<numbers[i];
            }
            /*/

            //=====T9=========
            a=numbers[0];
            //qDebug()<<iter_table->q;
            for(i=1;i<=Index;i++)
            {
                a=(a<<iter_table->q)+numbers[i];
                //qDebug()<<a<<a.length()<<iter_table->q<<numbers[i];
            }
            //qDebug()<<"";
            forSwitch=5;
            break;
        }
        case 5://T10
        {
            k++;
            iter_table++;
            if(!C.isEmpty())
            switch(C.pop())
            {
            case -1:
            {
                /*/
                qDebug()<<"a=  "<<a;
                qDebug()<<"z=  "<<z;
                if(a==z)
                {
                    qDebug()<<"a=z";
                }
                /*/
                return a;
                break;
            }
            case -2:
            {
                W<<a;
                forSwitch=4;
                //qDebug()<<"-2";
                break;
            }
            case -3:
            {
                forSwitch=3;
                //qDebug()<<"-3";
                break;
            }
            default:
            {
                //qDebug()<<"error";
                break;
            }
            }
            else
            {
                //qDebug()<<"Error algorithm.cpp: C Empty";
            }

            break;
        }
        }
    }
}