mirror of
https://github.com/rdkit/rdkit.git
synced 2026-06-05 22:04:27 +08:00
initial import
This commit is contained in:
337
Code/DataStructs/SparseBitVect.cpp
Executable file
337
Code/DataStructs/SparseBitVect.cpp
Executable file
@@ -0,0 +1,337 @@
|
||||
// $Id: SparseBitVect.cpp 5062 2006-03-08 01:43:55Z glandrum $
|
||||
//
|
||||
// Copyright (c) 2001-2006 greg Landrum and Rational Discovery LLC
|
||||
//
|
||||
// @@ All Rights Reserved @@
|
||||
//
|
||||
#include "SparseBitVect.h"
|
||||
#include <RDBoost/Exceptions.h>
|
||||
|
||||
#include "base64.h"
|
||||
#include <RDGeneral/StreamOps.h>
|
||||
#include <sstream>
|
||||
#include <limits>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <ios>
|
||||
#endif
|
||||
|
||||
|
||||
// """ -------------------------------------------------------
|
||||
//
|
||||
// Construct a SparseBitVect from a binary string.
|
||||
// The format of the string should be
|
||||
// the format produced by SparseBitVect::ToString
|
||||
//
|
||||
// """ -------------------------------------------------------
|
||||
SparseBitVect::SparseBitVect(const std::string s)
|
||||
{
|
||||
d_size=0;dp_bits = 0;
|
||||
InitFromText(s.c_str(),s.length());
|
||||
}
|
||||
|
||||
|
||||
// """ -------------------------------------------------------
|
||||
//
|
||||
// Construct a SparseBitVect from a binary string stored as a char *.
|
||||
// The format of the string should be
|
||||
// the format produced by SparseBitVect::ToString
|
||||
//
|
||||
// """ -------------------------------------------------------
|
||||
SparseBitVect::SparseBitVect(const char *data,const unsigned int dataLen)
|
||||
{
|
||||
d_size=0;dp_bits = 0;
|
||||
InitFromText(data,dataLen);
|
||||
}
|
||||
|
||||
// """ -------------------------------------------------------
|
||||
//
|
||||
// Operator[]
|
||||
// Returns the state of the ith bit.
|
||||
//
|
||||
// **C++ NOTE** The state of BitVects cannot be changed using
|
||||
// operator&. So this will not work:
|
||||
// SBV[i] = 0;
|
||||
// In Python this type of assignment **is** valid.
|
||||
//
|
||||
// """ -------------------------------------------------------
|
||||
bool
|
||||
SparseBitVect::operator[](const unsigned int which) const
|
||||
{
|
||||
if(which < 0 || which >= d_size){
|
||||
throw IndexErrorException(which);
|
||||
}
|
||||
if(dp_bits->count(which)) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
// """ -------------------------------------------------------
|
||||
//
|
||||
// Assignment operator
|
||||
// The bits of the other SBV are copied.
|
||||
//
|
||||
// """ -------------------------------------------------------
|
||||
SparseBitVect&
|
||||
SparseBitVect::operator=(const SparseBitVect& other)
|
||||
{
|
||||
IntSet *bv=other.dp_bits;
|
||||
if(dp_bits) delete dp_bits;
|
||||
d_size = other.GetNumBits();
|
||||
dp_bits = new IntSet;
|
||||
std::copy(bv->begin(),bv->end(),std::inserter(*dp_bits,dp_bits->end()));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------
|
||||
//
|
||||
// Operator|
|
||||
// allows SBV3 = SBV1|SBV2;
|
||||
//
|
||||
// -------------------------------------------------------
|
||||
SparseBitVect
|
||||
SparseBitVect::operator| (const SparseBitVect &other) const
|
||||
{
|
||||
SparseBitVect ans(d_size);
|
||||
std::set_union(dp_bits->begin(),dp_bits->end(),
|
||||
other.dp_bits->begin(),other.dp_bits->end(),
|
||||
std::inserter(*(ans.dp_bits),ans.dp_bits->end()));
|
||||
return ans;
|
||||
}
|
||||
|
||||
// """ -------------------------------------------------------
|
||||
//
|
||||
// Operator&
|
||||
// allows SBV3 = SBV1&SBV2;
|
||||
//
|
||||
// """ -------------------------------------------------------
|
||||
SparseBitVect
|
||||
SparseBitVect::operator& (const SparseBitVect &other) const
|
||||
{
|
||||
SparseBitVect ans(d_size);
|
||||
std::set_intersection(dp_bits->begin(),dp_bits->end(),
|
||||
other.dp_bits->begin(),other.dp_bits->end(),
|
||||
std::inserter(*(ans.dp_bits),ans.dp_bits->end()));
|
||||
return ans;
|
||||
}
|
||||
|
||||
// """ -------------------------------------------------------
|
||||
//
|
||||
// Operator^
|
||||
// allows SBV3 = SBV1^SBV2;
|
||||
//
|
||||
// """ -------------------------------------------------------
|
||||
SparseBitVect
|
||||
SparseBitVect::operator^ (const SparseBitVect &other) const
|
||||
{
|
||||
SparseBitVect ans(d_size);
|
||||
std::set_symmetric_difference(dp_bits->begin(),dp_bits->end(),
|
||||
other.dp_bits->begin(),other.dp_bits->end(),
|
||||
std::inserter(*(ans.dp_bits),ans.dp_bits->end()));
|
||||
return(ans);
|
||||
}
|
||||
|
||||
// """ -------------------------------------------------------
|
||||
//
|
||||
// Operator~ (the negation operator)
|
||||
// allows SBV2 = ~SBV1;
|
||||
//
|
||||
// """ -------------------------------------------------------
|
||||
SparseBitVect
|
||||
SparseBitVect::operator~ () const
|
||||
{
|
||||
SparseBitVect ans(d_size);
|
||||
for(unsigned int i=0;i<d_size;i++){
|
||||
if(!GetBit(i)) ans.SetBit(i);
|
||||
}
|
||||
|
||||
return(ans);
|
||||
}
|
||||
|
||||
// """ -------------------------------------------------------
|
||||
//
|
||||
// GetBit(int which)
|
||||
// Returns the state of bit which
|
||||
//
|
||||
// """ -------------------------------------------------------
|
||||
bool
|
||||
SparseBitVect::GetBit(const unsigned int which) const
|
||||
{
|
||||
if(which < 0 || which >= d_size){
|
||||
throw IndexErrorException(which);
|
||||
}
|
||||
if(dp_bits->count(which)) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
|
||||
// """ -------------------------------------------------------
|
||||
//
|
||||
// GetBit(const IntVectIter which) (C++ SPECIFIC)
|
||||
// Returns the state of bit which
|
||||
//
|
||||
// """ -------------------------------------------------------
|
||||
bool
|
||||
SparseBitVect::GetBit (const IntVectIter which) const
|
||||
{
|
||||
if(*which < 0 || static_cast<unsigned int>(*which) >= d_size){
|
||||
throw IndexErrorException(*which);
|
||||
}
|
||||
if(dp_bits->count(*which)) return true;
|
||||
else return false;
|
||||
|
||||
}
|
||||
|
||||
// """ -------------------------------------------------------
|
||||
//
|
||||
// GetBit(const IntSetIter which) (C++ SPECIFIC)
|
||||
// Returns the state of bit which
|
||||
//
|
||||
// """ -------------------------------------------------------
|
||||
bool
|
||||
SparseBitVect::GetBit (const IntSetIter which) const
|
||||
{
|
||||
if(*which < 0 || static_cast<unsigned int>(*which) >= d_size){
|
||||
throw IndexErrorException(*which);
|
||||
}
|
||||
if(dp_bits->count(*which)) return true;
|
||||
else return false;
|
||||
|
||||
}
|
||||
|
||||
// """ -------------------------------------------------------
|
||||
//
|
||||
// Sets bit which to be on.
|
||||
//
|
||||
// Returns the original state of the bit
|
||||
//
|
||||
// """ -------------------------------------------------------
|
||||
bool
|
||||
SparseBitVect::SetBit(const unsigned int which)
|
||||
{
|
||||
if(!dp_bits){
|
||||
throw ValueErrorException("BitVect not properly initialized.");
|
||||
}
|
||||
std::pair<IntSetIter,bool> res;
|
||||
if(which < 0 || which >= d_size){
|
||||
throw IndexErrorException(which);
|
||||
}
|
||||
res = dp_bits->insert(which);
|
||||
return !(res.second);
|
||||
}
|
||||
|
||||
// """ -------------------------------------------------------
|
||||
//
|
||||
// SetBit(const IntSetIter which) (C++ SPECIFIC)
|
||||
// Sets bit which to be on.
|
||||
//
|
||||
// Returns the original state of the bit
|
||||
//
|
||||
// """ -------------------------------------------------------
|
||||
bool
|
||||
SparseBitVect::SetBit(const IntSetIter which)
|
||||
{
|
||||
if(!dp_bits){
|
||||
throw ValueErrorException("BitVect not properly initialized.");
|
||||
}
|
||||
std::pair<IntSetIter,bool> res;
|
||||
if(*which < 0 || static_cast<unsigned int>(*which) >= d_size){
|
||||
throw IndexErrorException(*which);
|
||||
}
|
||||
res = dp_bits->insert(*which);
|
||||
return !(res.second);
|
||||
}
|
||||
|
||||
// """ -------------------------------------------------------
|
||||
//
|
||||
// Sets bit which to be off.
|
||||
//
|
||||
// Returns the original state of the bit
|
||||
//
|
||||
// """ -------------------------------------------------------
|
||||
bool
|
||||
SparseBitVect::UnSetBit(const unsigned int which)
|
||||
{
|
||||
if(!dp_bits){
|
||||
throw ValueErrorException("BitVect not properly initialized.");
|
||||
}
|
||||
if(which < 0 || which >= d_size){
|
||||
throw IndexErrorException(which);
|
||||
}
|
||||
|
||||
if(dp_bits->count(which)){
|
||||
dp_bits->erase(dp_bits->find(which));
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// """ -------------------------------------------------------
|
||||
//
|
||||
// GetOnBits(IntVect &which)
|
||||
// C++: Passes the set of on bits out in the IntVect passed in.
|
||||
// The contents of IntVect are destroyed.
|
||||
//
|
||||
// Python: Returns the tuple of on bits
|
||||
//
|
||||
// """ -------------------------------------------------------
|
||||
void
|
||||
SparseBitVect::GetOnBits(IntVect& v) const
|
||||
{
|
||||
if(!dp_bits){
|
||||
throw ValueErrorException("BitVect not properly initialized.");
|
||||
}
|
||||
unsigned int nOn = GetNumOnBits();
|
||||
if(!v.empty()) IntVect().swap(v);
|
||||
v.reserve(nOn);
|
||||
v.resize(nOn);
|
||||
std::copy(dp_bits->begin(),dp_bits->end(),v.begin());
|
||||
};
|
||||
|
||||
// """ -------------------------------------------------------
|
||||
//
|
||||
// ToString()
|
||||
// Returns a binary string with the contents of the BitVector
|
||||
//
|
||||
// """ -------------------------------------------------------
|
||||
std::string SparseBitVect::ToString() const {
|
||||
// This Function replaces the older version (version 16) of writing the onbits to
|
||||
// a string
|
||||
// the old version does not perform any run length encoding, it only checks to see if
|
||||
// the length of the bitvect can be short ints and writes the on bits as shorts
|
||||
// other wise the onbits are all written as ints
|
||||
|
||||
// here we do run length encoding and the version number has been bumped to 32 as well.
|
||||
// only the reader needs to take care of readinf all legacy versions
|
||||
// also in this scheme each bit number written to the string is checked to see how many
|
||||
// bytes it needs
|
||||
std::stringstream ss(std::ios_base::binary|std::ios_base::out|std::ios_base::in);
|
||||
|
||||
unsigned int nOnBits=GetNumOnBits();
|
||||
int tVers =ci_BITVECT_VERSION*-1;
|
||||
|
||||
ss.write((const char *)&(tVers),sizeof(tVers));
|
||||
ss.write((const char *)&d_size,sizeof(d_size));
|
||||
ss.write((const char *)&nOnBits,sizeof(nOnBits));
|
||||
int prev = -1;
|
||||
unsigned int zeroes;
|
||||
for (IntSetIter i=dp_bits->begin(); i!=dp_bits->end(); i++) {
|
||||
zeroes = *i - prev -1;
|
||||
RDKit::appendPackedIntToStream(ss, zeroes);
|
||||
prev = *i;
|
||||
}
|
||||
zeroes = d_size - prev -1;
|
||||
RDKit::appendPackedIntToStream(ss, zeroes);
|
||||
|
||||
std::string res(ss.str());
|
||||
return res;
|
||||
}
|
||||
|
||||
void SparseBitVect::_InitForSize(unsigned int size){
|
||||
d_size=size;
|
||||
if(dp_bits) delete dp_bits;
|
||||
dp_bits=new IntSet;
|
||||
};
|
||||
Reference in New Issue
Block a user