finishing bitvector
This commit is contained in:
		
							parent
							
								
									e42987061f
								
							
						
					
					
						commit
						50b2447535
					
				
							
								
								
									
										41
									
								
								bitvector.h
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								bitvector.h
									
									
									
									
									
								
							@ -21,8 +21,12 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "vec.h"
 | 
					#include "vec.h"
 | 
				
			||||||
#include "numbers.h"
 | 
					#include "numbers.h"
 | 
				
			||||||
 | 
					#include "laerror.h"
 | 
				
			||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//TODO: if efficiency is requires, make also a monic_bitvector, which will not store the leading 1 explicitly
 | 
				
			||||||
 | 
					//and then the field operations will be done without any resize
 | 
				
			||||||
 | 
					//To avoid confusion this class must NOT be derived from bitvector and have only explicit constructor conversion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace LA {
 | 
					namespace LA {
 | 
				
			||||||
//compressed storage of large bit vectors
 | 
					//compressed storage of large bit vectors
 | 
				
			||||||
@ -46,6 +50,19 @@ public:
 | 
				
			|||||||
	explicit bitvector (const unsigned int n):NRVec<bitvector_block>((n+blockbits-1)/blockbits) {modulo=n%blockbits; memset(v,0,nn*sizeof(bitvector_block));};
 | 
						explicit bitvector (const unsigned int n):NRVec<bitvector_block>((n+blockbits-1)/blockbits) {modulo=n%blockbits; memset(v,0,nn*sizeof(bitvector_block));};
 | 
				
			||||||
	bitvector (const bitvector_block a, const unsigned int n):NRVec<bitvector_block>(a,(n+blockbits-1)/blockbits) {modulo=n%blockbits;};
 | 
						bitvector (const bitvector_block a, const unsigned int n):NRVec<bitvector_block>(a,(n+blockbits-1)/blockbits) {modulo=n%blockbits;};
 | 
				
			||||||
	bitvector(const bitvector &rhs) : NRVec<bitvector_block>(rhs) {modulo=rhs.modulo;};
 | 
						bitvector(const bitvector &rhs) : NRVec<bitvector_block>(rhs) {modulo=rhs.modulo;};
 | 
				
			||||||
 | 
						explicit bitvector(const uint8_t *data, const unsigned int n): NRVec<bitvector_block>((n+blockbits-1)/blockbits) 
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
							modulo=n%blockbits;
 | 
				
			||||||
 | 
							if(endianity()) laerror("not portable to big endian");
 | 
				
			||||||
 | 
							else memcpy(&v[0],data,(n+7)/8);
 | 
				
			||||||
 | 
							zero_padding();
 | 
				
			||||||
 | 
							};      
 | 
				
			||||||
 | 
						void getdata(uint8_t *data)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
							if(endianity()) laerror("not portable to big endian");
 | 
				
			||||||
 | 
					                else memcpy(data,&v[0],(size()+7)/8);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	//operator= seems to be correctly synthetized by the compiler
 | 
						//operator= seems to be correctly synthetized by the compiler
 | 
				
			||||||
	//override dereferencing to address single bits, is however possible
 | 
						//override dereferencing to address single bits, is however possible
 | 
				
			||||||
	//only in the const context (otherwise we would have to define a type which, when assigned to, changes a single bit - possible but probably inefficient)
 | 
						//only in the const context (otherwise we would have to define a type which, when assigned to, changes a single bit - possible but probably inefficient)
 | 
				
			||||||
@ -57,9 +74,27 @@ public:
 | 
				
			|||||||
	bitvector_block getblock(const unsigned int i) const {return v[i];}; //integer interpretation
 | 
						bitvector_block getblock(const unsigned int i) const {return v[i];}; //integer interpretation
 | 
				
			||||||
	void setblock(const unsigned int i, const bitvector_block b) {v[i]=b;};
 | 
						void setblock(const unsigned int i, const bitvector_block b) {v[i]=b;};
 | 
				
			||||||
	int getblocksize() const {return 8*sizeof(bitvector_block);};
 | 
						int getblocksize() const {return 8*sizeof(bitvector_block);};
 | 
				
			||||||
	void set(const unsigned int i) {v[i/blockbits] |= (1UL<<(i%blockbits));};
 | 
						void set(const unsigned int i) 
 | 
				
			||||||
	void reset(const unsigned int i) {v[i/blockbits] &= ~(1UL<<(i%blockbits));};
 | 
							{
 | 
				
			||||||
	void flip(const unsigned int i) {v[i/blockbits] ^= (1UL<<(i%blockbits));};
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
							if(i>=size()) laerror("bitvector index out of range in");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
							v[i/blockbits] |= (1UL<<(i%blockbits));
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						void reset(const unsigned int i) 
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
					#ifdef DEBUG    
 | 
				
			||||||
 | 
					                if(i>=size()) laerror("bitvector index out of range in");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
							v[i/blockbits] &= ~(1UL<<(i%blockbits));
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						void flip(const unsigned int i) 
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
					#ifdef DEBUG    
 | 
				
			||||||
 | 
					                if(i>=size()) laerror("bitvector index out of range in");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
							v[i/blockbits] ^= (1UL<<(i%blockbits));
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
	const bool assign(const unsigned int i, const bool r) {if(r) set(i); else reset(i); return r;};
 | 
						const bool assign(const unsigned int i, const bool r) {if(r) set(i); else reset(i); return r;};
 | 
				
			||||||
	void clear() {copyonwrite(true); memset(v,0,nn*sizeof(bitvector_block));};
 | 
						void clear() {copyonwrite(true); memset(v,0,nn*sizeof(bitvector_block));};
 | 
				
			||||||
	void fill() {memset(v,0xff,nn*sizeof(bitvector_block));};
 | 
						void fill() {memset(v,0xff,nn*sizeof(bitvector_block));};
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										24
									
								
								numbers.cc
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								numbers.cc
									
									
									
									
									
								
							@ -117,6 +117,23 @@ return y;
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//avoiding overflow which would occur very soon in (x*y)%m
 | 
				
			||||||
 | 
					template <typename N>
 | 
				
			||||||
 | 
					N multmod(N x, N y, const N &m)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					N sum=0;
 | 
				
			||||||
 | 
					if(y==0) return 0;
 | 
				
			||||||
 | 
					while(x)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						if(x&1) sum= (sum+y)%m;
 | 
				
			||||||
 | 
						x>>=1;
 | 
				
			||||||
 | 
						y = (y<<1)%m; //still can overflow here but for much larger numbers
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					return sum;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <typename N>
 | 
					template <typename N>
 | 
				
			||||||
N powmod(const N &x, N i, const N &m)
 | 
					N powmod(const N &x, N i, const N &m)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -126,14 +143,14 @@ N y,z;
 | 
				
			|||||||
z=x%m;            
 | 
					z=x%m;            
 | 
				
			||||||
while(!(i&1))   
 | 
					while(!(i&1))   
 | 
				
			||||||
        {       
 | 
					        {       
 | 
				
			||||||
        z = (z*z)%m;
 | 
					        z = multmod(z,z,m);
 | 
				
			||||||
        i >>= 1;
 | 
					        i >>= 1;
 | 
				
			||||||
        }       
 | 
					        }       
 | 
				
			||||||
y=z;    
 | 
					y=z;    
 | 
				
			||||||
while((i >>= 1)/*!=0*/)
 | 
					while((i >>= 1)/*!=0*/)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                z = (z*z)%m;
 | 
							z = multmod(z,z,m);
 | 
				
			||||||
                if(i&1) y = (y*z)%m;
 | 
					                if(i&1) y = multmod(y,z,m);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
return y;
 | 
					return y;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -151,6 +168,7 @@ template N nextprime(N x); \
 | 
				
			|||||||
template std::ostream & operator<<(std::ostream &s, const FACTORIZATION<N>  &x); \
 | 
					template std::ostream & operator<<(std::ostream &s, const FACTORIZATION<N>  &x); \
 | 
				
			||||||
template N pow(const N &x, N i); \
 | 
					template N pow(const N &x, N i); \
 | 
				
			||||||
template N powmod(const N &x, N i, const N &m); \
 | 
					template N powmod(const N &x, N i, const N &m); \
 | 
				
			||||||
 | 
					template N multmod(N x, N i, const N &m); \
 | 
				
			||||||
template N eulerphi(const FACTORIZATION<N> &f); \
 | 
					template N eulerphi(const FACTORIZATION<N> &f); \
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -65,6 +65,10 @@ N pow(const N &x, N i);
 | 
				
			|||||||
template <typename N>
 | 
					template <typename N>
 | 
				
			||||||
N powmod(const N &x, N i, const N &m);
 | 
					N powmod(const N &x, N i, const N &m);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename N>
 | 
				
			||||||
 | 
					N multmod(N x, N y, const N &m);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}//namespace
 | 
					}//namespace
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										6
									
								
								t.cc
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								t.cc
									
									
									
									
									
								
							@ -2944,6 +2944,12 @@ if(0)
 | 
				
			|||||||
uint64_t n;
 | 
					uint64_t n;
 | 
				
			||||||
cin >>n;
 | 
					cin >>n;
 | 
				
			||||||
cout <<factorization(n)<<" phi = "<<eulerphi(n)<<endl;
 | 
					cout <<factorization(n)<<" phi = "<<eulerphi(n)<<endl;
 | 
				
			||||||
 | 
					uint64_t a;
 | 
				
			||||||
 | 
					do {
 | 
				
			||||||
 | 
						a=RANDINT64()%n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}while(gcd(a,n)!=1);
 | 
				
			||||||
 | 
					cout <<"E-F test "<<powmod(a,eulerphi(n),n)<<endl;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if(0)
 | 
					if(0)
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user