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; }
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; } } } }