ArrayXd GoSUM::CModelVariables::expandedNTuple(int _at) const { int i,j,k,N=int(mvs.size()),eN=expandedSize(),exsize; ArrayXd eX=ArrayXd::Zero(eN); for ( i=j=0; i<N; i++,j+=exsize ) { exsize=mvs[i].expandedSize(); if ( exsize==1 ) { eX(j)=mvs[i].sampleValue(_at); } else { for ( k=0; k<exsize; k++ ) if (k==mvs[i].sampleValue(_at)) { eX(j+k) = 1.; break; } } } return eX; }
UString &UString::append(unsigned short c) { int thisOffset = rep->offset; int length = size(); // possible cases: if (length == 0) { // this is empty - must make a new rep because we don't want to pollute the shared empty one int newCapacity = expandedSize(1, 0); UChar *d = static_cast<UChar *>(malloc(sizeof(UChar) * newCapacity)); d[0] = c; release(); rep = Rep::create(d, 1); rep->capacity = newCapacity; } else if (!rep->baseString && rep->rc == 1) { // this is direct and has refcount of 1 (so we can just alter it directly) expandCapacity(thisOffset + length + 1); UChar *d = const_cast<UChar *>(data()); d[length] = c; rep->len = length + 1; rep->_hash = 0; } else if (thisOffset + length == usedCapacity()) { // this reaches the end of the string - extend it and share expandCapacity(thisOffset + length + 1); UChar *d = const_cast<UChar *>(data()); d[length] = c; Rep *newRep = Rep::create(rep, 0, length + 1); release(); rep = newRep; } else { // this is shared with someone using more capacity, gotta make a whole new string int newCapacity = expandedSize((length + 1), 0); UChar *d = static_cast<UChar *>(malloc(sizeof(UChar) * newCapacity)); memcpy(d, data(), length * sizeof(UChar)); d[length] = c; release(); rep = Rep::create(d, length); rep->capacity = newCapacity; } return *this; }
ArrayXd GoSUM::CModelVariables::expandNTuple(const ArrayXd &X) const { if ( X.size()!=mvs.size() ) throw "GoSUM::CModelVariables::expand error: wrong X size"; int i,j,k,N=int(mvs.size()),eN=expandedSize(),exsize; ArrayXd eX=ArrayXd::Zero(eN); for ( i=j=0; i<N; i++,j+=exsize ) { exsize=mvs[i].expandedSize(); if ( exsize==1 ) { eX(j)=X(i); } else { for ( k=0; k<exsize; k++ ) if (k==X(i)) { eX(j+k) = 1.; break; } } } return eX; }
void UString::expandCapacity(int requiredLength) { Rep *r = rep->baseString ? rep->baseString : rep; if (requiredLength > r->capacity) { int newCapacity = expandedSize(requiredLength, r->preCapacity); r->buf = static_cast<UChar *>(realloc(r->buf, newCapacity * sizeof(UChar))); r->capacity = newCapacity - r->preCapacity; } if (requiredLength > r->usedCapacity) { r->usedCapacity = requiredLength; } }
UString &UString::append(const char *t) { int thisSize = size(); int thisOffset = rep->offset; int tSize = strlen(t); int length = thisSize + tSize; // possible cases: if (thisSize == 0) { // this is empty *this = t; } else if (tSize == 0) { // t is empty, we'll just return *this below. } else if (!rep->baseString && rep->rc == 1) { // this is direct and has refcount of 1 (so we can just alter it directly) expandCapacity(thisOffset + length); UChar *d = const_cast<UChar *>(data()); for (int i = 0; i < tSize; ++i) d[thisSize+i] = t[i]; rep->len = length; rep->_hash = 0; } else if (thisOffset + thisSize == usedCapacity()) { // this string reaches the end of the buffer - extend it expandCapacity(thisOffset + length); UChar *d = const_cast<UChar *>(data()); for (int i = 0; i < tSize; ++i) d[thisSize+i] = t[i]; Rep *newRep = Rep::create(rep, 0, length); release(); rep = newRep; } else { // this is shared with someone using more capacity, gotta make a whole new string int newCapacity = expandedSize(length, 0); UChar *d = static_cast<UChar *>(malloc(sizeof(UChar) * newCapacity)); memcpy(d, data(), thisSize * sizeof(UChar)); for (int i = 0; i < tSize; ++i) d[thisSize+i] = t[i]; release(); rep = Rep::create(d, length); rep->capacity = newCapacity; } return *this; }
UString::UString(const UString &a, const UString &b) { int aSize = a.size(); int aOffset = a.rep->offset; int bSize = b.size(); int bOffset = b.rep->offset; int length = aSize + bSize; // possible cases: if (aSize == 0) { // a is empty attach(b.rep); } else if (bSize == 0) { // b is empty attach(a.rep); } else if (aOffset + aSize == a.usedCapacity() && 4 * aSize >= bSize && (-bOffset != b.usedPreCapacity() || aSize >= bSize)) { // - a reaches the end of its buffer so it qualifies for shared append // - also, it's at least a quarter the length of b - appending to a much shorter // string does more harm than good // - however, if b qualifies for prepend and is longer than a, we'd rather prepend UString x(a); x.expandCapacity(aOffset + length); memcpy(const_cast<UChar *>(a.data() + aSize), b.data(), bSize * sizeof(UChar)); rep = Rep::create(a.rep, 0, length); } else if (-bOffset == b.usedPreCapacity() && 4 * bSize >= aSize) { // - b reaches the beginning of its buffer so it qualifies for shared prepend // - also, it's at least a quarter the length of a - prepending to a much shorter // string does more harm than good UString y(b); y.expandPreCapacity(-bOffset + aSize); memcpy(const_cast<UChar *>(b.data() - aSize), a.data(), aSize * sizeof(UChar)); rep = Rep::create(b.rep, -aSize, length); } else { // a does not qualify for append, and b does not qualify for prepend, gotta make a whole new string int newCapacity = expandedSize(length, 0); UChar *d = static_cast<UChar *>(malloc(sizeof(UChar) * newCapacity)); memcpy(d, a.data(), aSize * sizeof(UChar)); memcpy(d + aSize, b.data(), bSize * sizeof(UChar)); rep = Rep::create(d, length); rep->capacity = newCapacity; } }
void UString::expandPreCapacity(int requiredPreCap) { Rep *r = rep->baseString ? rep->baseString : rep; if (requiredPreCap > r->preCapacity) { int newCapacity = expandedSize(requiredPreCap, r->capacity); int delta = newCapacity - r->capacity - r->preCapacity; UChar *newBuf = static_cast<UChar *>(malloc(newCapacity * sizeof(UChar))); memcpy(newBuf + delta, r->buf, (r->capacity + r->preCapacity) * sizeof(UChar)); free(r->buf); r->buf = newBuf; r->preCapacity = newCapacity - r->capacity; } if (requiredPreCap > r->usedPreCapacity) { r->usedPreCapacity = requiredPreCap; } }
void GoSUM::CModelVariables::setNormalization() { int i,j,N=size(),eN=expandedSize(),exsize; trn.setZero(eN); scl.setOnes(eN); for ( i=0,j=0; i<N; i++ ) { const CModelVariable &aMV=mvs[i]; exsize=aMV.expandedSize(); if ( exsize==1 ) { // trn(j)=aMV.minValue(); // scl(j)=aMV.maxValue()-aMV.minValue(); trn(j)=aMV.expectedValue(); scl(j)=sqrt(aMV.variance()); if ( fabs(scl(j))<TINY ) { trn(j)+=1.; scl(j)=1.; } } j+=exsize; } }