📄 packmat.cc.txt
字号:
PackVec::PackVec(istream &Densefile){ PackVec_is(Densefile);}voidPackVec::PackVec_is(istream &Densefile){ int i,j,k1; PKSIZE blob; int bit; Densefile>>numrows; setsize(*this,numrows); callocvec(*this); for(i=0;i< numpackrows1;i++) { for(k1 = 0; k1 < PackMat::bitsper; k1++) { Densefile >> bit; Vec[i] = (bit << k1) | Vec[i]; } } if(fracbits) { i = numpackrows1; for(k1 = 0; k1 < fracbits; k1++) { Densefile >> bit; Vec[i] = (bit << k1) | Vec[i]; } }}voidPackVec::Size(int rows)// resize, but do not attempt to preserve the contents{ int i,j; checkandset(*this,rows); for(j = 0; j < numpackrows; j++) { Vec[i] = 0; }}voidPackVec::Size(PackVec &A)// resize to the same size as A, but do not attempt to preserve the contents{ Size(A.numrows);}PackVec &PackVec::operator=(PackVec &DM2){ int i,j; checkandset(*this,DM2.numrows); for(i=0;i<numpackrows;i++) Vec[i] = DM2.Vec[i]; return *this;}PackVec::~PackVec(void){ numrows = numpackrows = numpackrows1 = numpackrows2 = 0; if(Vec) delete[] Vec; Vec = 0;}int PackVec::GetVal(int row){ int vb, row1, row2; row1 = row >> PackMat::shifter; row2 = row % PackMat::bitsper; vb = (Vec[row1] & (1<<row2)) >> row2; return vb;}void PackVec::SetVal(int row, int val){ int i,j,k, col1, row1; int bitcol, bitrow; PKSIZE value; row1 = row >> PackMat::shifter; bitrow = row % PackMat::bitsper; if(!val) { // set value to 0 Vec[row1] &= ~(1<<bitrow); } else { Vec[row1] |= (1<<bitrow); }}void PackVec::Mult(PackMat &DM, PackVec &Prod){// This function tests to make sure things are the right size// and then calls the multiplication function if(DM.packmode == VERTPACK) { if(numrows != DM.numrows) { // correct size to multiply cerr << "Error: Matrices not conformable in product\n"; exit(-1); } checkandset(Prod,DM.numcols); Multnocheck(DM,Prod); } else { cerr << "Multiplication not implemented for these matrix modes\n"; exit(-1); }}void PackVec::Multnocheck(PackMat &DM, PackVec &Prod){// This function does not testing --- it assumes that// everything is the right size and shape for multiplication int i,j,k,nj,j1,k1; PKSIZE temp; int prodwt; nj = DM.numcols/PackMat::bitsper; j1 = 0; for(j = 0; j < nj; j++) { Prod.Vec[j] = 0; for(k1 = 0; k1 < PackMat::bitsper; k1++) { prodwt = 0; for(k = 0; k < numpackrows;k ++) { prodwt += PackMat::getWeight(Vec[k] & DM.Matrix[k][j1]); } Prod.Vec[j] = ((prodwt % 2)<<k1) + Prod.Vec[j]; j1++; } } // do the last fractbits if(Prod.fracbits) { j = nj; Prod.Vec[j] = 0; for(k1 = 0; k1 < Prod.fracbits; k1++) { prodwt = 0; for(k = 0; k < numpackrows;k ++) { prodwt += PackMat::getWeight(Vec[k] & DM.Matrix[k][j1]); } Prod.Vec[j] = ((prodwt % 2)<<k1) + Prod.Vec[j]; j1++; } }}inline voidPackVec::checkandset(PackVec &B,int brows){ if(!(B.numrows == brows)) { if(B.Vec) { delete[] B.Vec;} setsize(B,brows); callocvec(B); } }inline voidPackVec::checkandset2(PackVec &B,int brows)// make sure there is at least brows, but possibly more{ if(B.numrows < brows) { if(B.Vec) { delete[] B.Vec;} setsize(B,brows); callocvec(B); } }voidPackVec::resize(PackVec &A,int rows)// set A to the right size, but keep all the old stuff that was there before{ PKSIZE *NewVec; int oldnumpackrows; int i; oldnumpackrows = A.numpackrows; setsize(A,rows); NewVec = new PKSIZE[A.numpackrows]; // clear out the matrix for(i = 0; i < oldnumpackrows; i++) { NewVec[i] = A.Vec[i]; } if(A.Vec) delete[] Vec; A.Vec = NewVec;}void PackVec::clearfringe(){ int i,j; PKSIZE mask; mask = (1<<fracbits)-1; Vec[numpackrows1] &= mask;}int PackVec::getWeight() // get the weight of the entire vector{ int i,j, wt; wt = 0; if(fracbits) { // make sure there is no extra stuff on edges clearfringe(); } for(i = 0; i < numpackrows; i++) { wt += PackMat::getWeight(Vec[i]); } return wt;}// print functionostream&PackVec:: printpackvec(ostream &os) const { int i,j,k,i1; for(i = 0; i < numpackrows1; i++) { for(i1 = 0; i1 < PackMat::bitsper; i1++) { if(Vec[i] & (1<<i1)) os << "1"; else os << "0"; os << printspace; } } for(i = 0; i < numpackrows2; i++) { for(i1 = 0; i1 < fracbits; i1++) { if(Vec[i+numpackrows1] & (1<<i1)) os << "1"; else os << "0"; os << printspace; } } return os;}void PackVec::PrintInfo(void){ cout<<"Rows = "<<numrows <<"Packrows: "<< numpackrows<< " " << numpackrows1 << " " << numpackrows2 << endl; cout << "fracbits: " << fracbits << endl;}voidPackVec::MakeRandom(double p){ int i,j,k; unsigned int rno; PKSIZE blob; PKSIZE mask; if(p == 0 || p == 0.5) { // if equal prob of 0 or 1 for(i = 0; i < numpackrows; i++) { blob = 0; for(k = 0; k < sizeof(PKSIZE); k++) { rno = 0xFFFF&(rand()>>8); // pick off two bytes blob = (blob << 16) + rno; } Vec[i] = blob; } // now make sure there is nothing left over if(fracbits) { clearfringe(); } } else { // else go by the probabilities double rnod; for(i = 0; i < numrows; i++) { rnod = double(rand())/double(RAND_MAX); if(rnod < p) SetVal(i,1); else SetVal(i,0); } }}voidPackVec::SetToZero(){ int i,j,k; unsigned int rno; PKSIZE blob; for(i = 0; i < numpackrows; i++) { Vec[i] = 0; }}voidPackVec::SetToOne(){ int i,j,k; unsigned int rno; PKSIZE blob; for(i = 0; i < numpackrows; i++) { Vec[i] = PackMat::masker; } // now make sure there is nothing left over clearfringe();}void PackVec::Add(PackVec &DM, PackVec &Sum){// This function tests to make sure things are the right size// and then calls the addition function if(!(numrows == DM.numrows)) { // correct size to add cerr << "Error: Matrices not same size in sum\n"; exit(-1); } checkandset(Sum,numrows); Addnocheck(DM,Sum);}void PackVec::Addnocheck(PackVec &DM, PackVec &Sum){// This function does no testing --- it assumes that// everything is the right size and shape for addition int i; for(i = 0; i < numpackrows; i++) { Sum.Vec[i] = Vec[i] ^ DM.Vec[i]; }}int PackVec::innerprod2(PackVec &row1, PackVec &row2, int start, int end)// do the inner product between two row-packed quantities{ int stbig, stlit, ebig, elit, i, nl; int sum=0; PKSIZE mask,mask1; int bitsdone=0; stbig = start/PackMat::bitsper; stlit = start % PackMat::bitsper; ebig = end/PackMat::bitsper; elit = end % PackMat::bitsper; mask1 = ((1<<(PackMat::bitsper-stlit))-1) << stlit; mask = mask1; for(i = stbig; i < ebig; i++) { sum += PackMat::getWeight(row1.Vec[i] & row2.Vec[i] & mask); mask = PackMat::masker; stlit = 0; } nl = elit-stlit+1; mask = ((1<<nl)-1)<<stlit; sum += PackMat::getWeight(row1.Vec[i] & row2.Vec[i] & mask); return sum % 2;}int PackVec::innerprod(PackVec &row1, PackVec &row2, int end)// do the inner product between two row-packed quantities, starting// at the first bit and covering end bits.{ int i, ebig, elit; int sum= 0; ebig = end/PackMat::bitsper; elit = end % PackMat::bitsper; for(i = 0; i < ebig; i++) { sum += PackMat::getWeight(row1.Vec[i] & row2.Vec[i]); } if(elit) { sum += PackMat::getWeight((row1.Vec[i]&row2.Vec[i]) & ((1<<elit)-1)); } return sum % 2;}void PackVec::Subvector(PackVec &subvec,int row1, int row2,int subrow) // extract the row or vector and place it (starting at subrow)// in the vector subvec{ int i,i1, nrows; if(row1 < 0) row1 = 0; if(row2 >= numrows) row2 = numrows-1; nrows = (row2-row1+1) + subrow; subvec.checkandset2(subvec,nrows); for(i=0, i1=subrow; i < (row2-row1+1); i++,i1++) { subvec.SetVal(i1,GetVal(i+row1)); }}voidstackside(PackMat & C,PackMat &A, PackMat & B, StackMode ssm, PackMode pkmode)// C = [A B]// Stack side by size. If not the same height, then use// the stacksidemode value (exact, top, bottom, center1st, center2nd, truncate){ int numzaboveA, numzaboveB, numzbelowA, numzbelowB, numArows, numBrows, numCrows, numCcols; int i,j; int numcolA,numcolB, numrowA,numrowB; StackMode ss; if(ssm == Default) { ss = PackMat::sidestackmode; } else { ss = ssm; } if(A.numrows && B.numrows && A.numrows != B.numrows && ss==Exact) { cerr << "Error in side stacking: not the same height\n"; exit(-1); } numcolA = A.numcols; numcolB = B.numcols; numrowA = A.numrows; numrowB = B.numrows; numCcols = numcolA + numcolB; numzaboveA = 0; // default values numzaboveB = 0; numzbelowA = 0; numzbelowB = 0; numArows = numrowA; numBrows = numrowB; numCrows = MAX(numrowA,numrowB); switch(ss) { case Exact: break; case Top: numzaboveA = 0; numzaboveB = 0; numzbelowA = MAX(numrowB - numrowA,0); numzbelowB = MAX(numrowA - numrowB,0); break; case Truncate: numArows = MIN(numrowA,numrowB); numBrows = numArows; numCrows = numArows; break; case Bottom: numzaboveA = MAX(numrowB - numrowA,0); numzaboveB = MAX(numrowA - numrowB,0); break; case Center: if(A.numrows > B.numrows) { numzaboveB = (numrowA - numrowB)/2; numzbelowB = (numrowA - numrowB - numzaboveB); } else { numzaboveA = (numrowB - numrowB)/2; numzbelowA = (numrowB - numrowA - numzaboveA); } break; default: cerr << "Error: invalid side stack mode\n"; exit(-1); break; } C.checkandresize2(C,pkmode, numCrows, numCcols);// cout << "C(resize)=\n" << C << endl;// cout << "numCcol=" << numCcols << endl;// cout << "numcolA=" << numcolA << endl; // The A column for(i = 0; i < numzaboveA; i++) { for(j = 0; j < numcolA; j++) { C.SetVal(i,j,0); } } for(i = 0; i < numArows; i++) { for(j = 0; j < numcolA; j++) { C.SetVal(i+numzaboveA,j,A.GetVal(i,j)); } } for(i = 0; i < numzbelowA; i++) { for(j = 0; j < numcolA; j++) { C.SetVal(i+numzaboveA+numArows,j,0); } } // The B column for(i = 0; i < numzaboveB; i++) { for(j = 0; j < numcolB; j++) { C.SetVal(i,j+numcolA,0); } } for(i = 0; i < numBrows; i++) { for(j = 0; j < numcolB; j++) { C.SetVal(i+numzaboveB,j+numcolA,B.GetVal(i,j)); } } for(i = 0; i < numzbelowB; i++) { for(j = 0; j < numcolB; j++) { C.SetVal(i+numzaboveB+numBrows,j+numcolA,0); } }}voidstacktop(PackMat & C,PackMat &A, PackMat & B, StackMode tsm, PackMode pkmode)// C = [A;B]// Stack A over B. If not the same width, then use// the stacktopmode value (exact, left, right, center, truncate){ int numzleftA, numzleftB, numzrightA, numzrightB, numAcols, numBcols, numCrows, numCcols; int i,j; int numcolA,numcolB, numrowA,numrowB; StackMode ts; if(tsm == Default) { ts = PackMat::topstackmode; } else { ts = tsm; } if(A.numcols && B.numcols && A.numcols != B.numcols && ts==Exact) { cerr << "Error in top stacking: not the same width\n"; exit(-1); } numcolA = A.numcols; numcolB = B.numcols; numrowA = A.numrows; numrowB = B.numrows; numCrows = numrowA + numrowB; numzleftA = 0; // default values numzleftB = 0; numzrightA = 0; numzrightB = 0; numAcols = numcolA; numBcols = numcolB; numCcols = MAX(numcolA,numcolB); switch(ts) { case Exact: break; case Left: numzleftA = 0; numzleftB = 0; numzrightA = MAX(numcolB - numcolA,0); numzrightB = MAX(numcolA - numcolB,0); break; case Truncate: numAcols = MIN(numcolA,numcolB); numBcols = numAcols; numCcols = numAcols; break; case Right: numzleftA = MAX(numcolB - numcolA,0); numzleftB = MAX(numcolA - numcolB,0); break; case Center: if(numcolA > numcolB) { numzleftB = (numcolA - numcolB)/2; numzrightB = (numcolA - numcolB - numzleftB); } else { numzleftA = (numcolB - numcolB)/2; numzrightA = (numcolB - numcolA - numzleftA); } break; default: cerr << "Invalid top stack mode\n"; exit(-1); break; } C.checkandresize2(C,pkmode, numCrows, numCcols);// cout << "C(resize)=\n" << C << endl; // The A row for(i = 0; i < numrowA; i++) { for(j = 0; j < numzleftA; j++) { C.SetVal(i,j,0); } } for(i = 0; i < numrowA; i++) { for(j = 0; j < numAcols; j++) { C.SetVal(i,j+numzleftA,A.GetVal(i,j)); } } for(i = 0; i < numrowA; i++) { for(j = 0; j < numzrightA; j++) { C.SetVal(i,j+numzleftA+numAcols,0); } } // The B row for(i = 0; i < numrowB; i++) { for(j = 0; j < numzleftB; j++) { C.SetVal(i+numrowA,j,0); } } for(i = 0; i < numrowB; i++) { for(j = 0; j < numBcols; j++) { C.SetVal(i+numrowA,j+numzleftB,B.GetVal(i,j)); } } for(i = 0; i < numrowB; i++) { for(j = 0; j < numzrightB; j++) { C.SetVal(i+numrowA,j+numBcols+numzleftB,0); } }}void setval(PKSIZE **Matrix,int row, int col, int val, PackMode packmode){ int i,j,k, col1, row1; int bitcol, bitrow; PKSIZE value; if(packmode == HORIZPACK) { col1 = col >> PackMat::shifter; bitcol = col % PackMat::bitsper; if(!val) { // set value to 0 Matrix[row][col1] &= ~(1<<bitcol); } else { // set value to 1 Matrix[row][col1] |= (1<<bitcol); } } else if(packmode == VERTPACK) { row1 = row >> PackMat::shifter; bitrow = row % PackMat::bitsper; if(!val) { // set value to 0 Matrix[row1][col] &= ~(1<<bitrow); } else { Matrix[row1][col] |= (1<<bitrow); } }}/*Local Variables:compile-command: "g++ -c -g PackMat.cc"End:*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -