⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ihisto.cpp

📁 wavelet codec there are 34 files with code about the wavelet theory
💻 CPP
字号:
#include <math.h>
#include <stdlib.h>
#include <iostream.h>
#include <iomanip.h>
#include <assert.h>
#include <math.h>
#include "global.h"
#include "iHisto.h"

iHistogram::iHistogram(int n, int maxct)
{
#if iHistDebug
	 debug = 1;
#endif
	 onelog2 = 1/log(2.0);
	 nsyms = n;
	 maxCt = maxct;
	 totalCount = 0;
	 count = new int[nsyms];
	 treeCount = new int[nsyms];
	 symToPos = new int[nsyms];
	 posToSym = new int[nsyms];

	 assert(count && treeCount && symToPos && posToSym);

	 for (int i = 0; i < nsyms; i++) {
	count[i] = 0;
	treeCount[i] = 0;
	symToPos[i] = i;
	posToSym[i] = i;
	 }
}

iHistogram::~iHistogram()
{
	 delete [] count;
	 delete [] treeCount;
	 delete [] symToPos;
	 delete [] posToSym;
}

#if 0
Real iHistogram::Entropy(int sym)
{
	 return -log(Count(sym)/(Real)totalCount) * onelog2;
}
#endif

void iHistogram::BuildTreeCount(void)
{
	 int i;
	 for (i = 0; i < nsyms; i++) { treeCount[i] = 0; }

	 for (i = nsyms - 1; i > 0; i--) {
		int pos = i;
		while (pos > 0) {
			int parent = Parent(pos);
			if (pos == Lchild(parent)) {
				treeCount[parent] += count[i];
			}
			pos = parent;
		}
	}
}


void iHistogram::swapSyms(int pos_a, int pos_b)
{
	 int sym_a = posToSym[pos_a];
	 int sym_b = posToSym[pos_b];
	 assert(symToPos[sym_a] == pos_a);
	 assert(symToPos[sym_b] == pos_b);

	 symToPos[sym_a] = pos_b;
	 symToPos[sym_b] = pos_a;

	 posToSym[pos_a] = sym_b;
	 posToSym[pos_b] = sym_a;

	 int t = count[pos_a];
	 count[pos_a] = count[pos_b];
	 count[pos_b] = t;

	 assert(symToPos[sym_a] == pos_b);
	 assert(symToPos[sym_b] == pos_a);
	 assert(posToSym[pos_a] == sym_b);
	 assert(posToSym[pos_b] == sym_a);

}

int iHistogram::sorted(int from, int to)
{
	 iHistDBbegin(this);
	 cerr << "sorted(" << from << ", " << to << ")->";
	 iHistDBend;
	 for (int i = from; i < to - 1; i++) {
	if (count[i] < count[i + 1]) {
		 iHistDBbegin(this);
		 cerr << 0 << "\n";
		 iHistDBend;
		 return 0;
	}
	 }
	 iHistDBbegin(this);
	 cerr << 1 << "\n";
	 iHistDBend;
	 return 1;
}

void iHistogram::pc(int from, int to)
{
	 cerr << "<" << from << ", " << to << ">";
	 for (int i = from; i < to; i++) {
	cerr << setw(4) << count[i];
	 }
	 cerr << "\n";
}

void iHistogram::qs(int from, int to)
{
    int pivot = from;
    int ub = to;
    
    iHistDBbegin(this);
    cerr << "qs(" << from << ", " << to << ")\n";
    cerr << "pivoting on " << count[pivot] << "\n";
    pc(from, to);
    iHistDBend;
    
    if (sorted(from, to)) return;

    swapSyms(pivot, (from + to) / 2); // pivot on middle
    
    while (pivot + 1 < ub) {
	if (count[pivot + 1] < count[pivot]) {
	    ub--;
	    iHistDBbegin(this);
	    cerr << "swapping count[" << (pivot + 1) << "]=" << count[pivot + 1] <<
		" and count[" << ub << "]=" << count[ub] << "\n";
	    iHistDBend;
	    swapSyms(pivot + 1, ub);
	} else {
	    iHistDBbegin(this);
	    cerr << "swapping count[" << (pivot + 1) << "]=" << count[pivot + 1] <<
		" and count[" << pivot << "]=" << count[pivot] << "\n";
	    iHistDBend;
	    swapSyms(pivot, pivot + 1);	
	    pivot++;
	}
	iHistDBbegin(this);
	pc(from, to);
	iHistDBend;
    }
    qs(from, pivot);
    qs(pivot + 1, to);
    
#if iHistDebug
    assert(sorted(from, to));
#endif

    iHistDBbegin(this);
    pc(from, to);
    iHistDBend;
    
}

void iHistogram::qsortSyms(void)
{
    qs(0, nsyms);
}


void iHistogram::ScaleCounts(void)
{
    totalCount = 0;
    for (int i = 0; i < nsyms; i++) {
	if (count[i] == 0) {
	    ;			// skip this one
	} else {
	    count[i] = count[i] / 2;
	    if (!count[i]) {
		count[i] = 1;
	    }
	    totalCount += count[i];
	}
    }
}

void iHistogram::InitCounts(int *cnts)
{
    totalCount = 0;
    for (int i = 0; i < nsyms; i++) {
	symToPos[i] = i;
	posToSym[i] = i;
	totalCount += cnts[i];
	count[i] = cnts[i];
    }
    while (totalCount >= maxCt) { ScaleCounts(); }
    qsortSyms();
    BuildTreeCount();
}

void iHistogram::InitCounts(iHistBinFun *f, void *closure)\
{
    totalCount = 0;
    f(closure, count);
    for (int i = 0; i < nsyms; i++) {
	symToPos[i] = i;
	posToSym[i] = i;
	totalCount += count[i];
    }
    while (totalCount >= maxCt) { ScaleCounts(); }
    qsortSyms();
    BuildTreeCount();
}


int iHistogram::TotalCount() { return totalCount; }

int iHistogram::LeftCount(int sym)
{
    int lc = 0;
    int pos = symToPos[sym];
    assert((sym >= 0) && (sym < nsyms));

    lc = treeCount[pos];

    while (pos) {
	int parent = Parent(pos);
	if (Rchild(parent) == pos) {
	    lc += treeCount[parent] + count[parent];
	}
	pos = parent;
    }

    return lc;
}

#if 0
int iHistogram::Count(int sym)
{
    assert((sym >= 0) && (sym < nsyms));

    return count[symToPos[sym]];
}
#endif

void iHistogram::Reorganise(int sym)
{
    int pos = symToPos[sym];

    if (!pos || count[pos - 1] > count[pos]) {
	return;
    }

    // find leftmost count == count[pos], then swap values

    int right = pos;
    int left  = 0;

    // make sure it isn't under left at start. We'll never put it 
    // there later.
    if (count[left] == count[pos]) { right = left; }

    while (left != right) {
	int middle = (left + right) / 2;
	if (count[middle] > count[pos]) {
	    //middle is to left of leftmost count == count[pos]
	    left = middle + 1;
	} else {
	    //leftmost count == count[pos] is either under middle, or to left
	    //of middle.
	    right = middle;
	}
    }

    assert(count[right] == count[pos]);
    assert(!right || count[right - 1] > count[pos]);

    int rsym = posToSym[right];

    symToPos[sym] = right;
    posToSym[pos] = posToSym[right];
    symToPos[rsym] = pos;
    posToSym[right] = sym;

    
}

void iHistogram::IncCount(int sym)
{
    iHistDBbegin(this) {
	cerr << "IncCount(" << sym << ")\n";
    } iHistDBend;
    
    assert((sym >= 0) && (sym < nsyms));

    Reorganise(sym);

    int pos = symToPos[sym];

    count[pos]++;
    totalCount++;

    while(pos > 0) {
	int parent = Parent(pos);
	if (pos == Lchild(parent)) {
	    treeCount[parent]++;
	}
	pos = parent;
    }

    if (totalCount >= maxCt) {
	ScaleCounts(); 
	BuildTreeCount();
    }
    assert(totalCount < maxCt);
}

int iHistogram::Symbol(int val)
{
    assert(val >= 0 && val < totalCount);

    iHistDBbegin(this) {
	cerr << "Symbol(" << val << ")\n";
    } iHistDBend;

    int pos = 0;    
    int leftSum = 0;
    
    while(1) {
	iHistDBbegin(this) {
	    cerr << "Symbol: pos= " << pos << " leftSum= " << leftSum << " ";
	    cerr << "treeCount[" << pos << "]=" << treeCount[pos] << " ";
	    cerr << "count[" << pos << "]=" << count[pos] << "\n";
	} iHistDBend;

	if (leftSum + treeCount[pos] > val) {
	    // look at left subtree
	    pos = Lchild(pos);
	} else {
	    if (val >= leftSum + treeCount[pos] + count[pos]) {
		// look at right subtree
		leftSum += treeCount[pos] + count[pos];
		pos = Rchild(pos);
	    } else {
		assert(val >= leftSum &&
		       val < leftSum + treeCount[pos] + count[pos]);
		iHistDBbegin(this) {
		    cerr << "Symbol: posToSym[" << pos << "]=" << posToSym[pos]
			 << "\n";
		} iHistDBend;
		return posToSym[pos];
	    }
	}
	assert(pos > 0 && pos < nsyms);
    }
}

void iHistogram::print(ostream &strm)
{
    strm << "iHistogram " << (void *)this << "\n";

    strm << "\ttotalCount=" << totalCount << "\n";

    strm << "\tmaxCt=" << maxCt << "\n";

    strm << "\tnsyms=" << nsyms << "\n";

    int i;
    strm << "symToPos  ";
    for (i = 0; i < nsyms; i++) { strm << setw(6) << symToPos[i] << " "; }
    strm << "\n";
    strm << "count     ";
    for (i = 0; i < nsyms; i++) { strm << setw(6) << count[i] << " "; }
    strm << "\n";
    strm << "treeCount ";
    for (i = 0; i < nsyms; i++) { strm << setw(6) << treeCount[i] << " "; }
    strm << "\n";
    strm << "posToSym  ";
    for (i = 0; i < nsyms; i++) { strm << setw(6) << posToSym[i] << " "; }
    strm << "\n";
}

void iHistogram::printerr() { print(cerr); }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -