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

📄 ihisto.cc

📁 VC小波算法1,高效率VC小波算法1
💻 CC
字号:
// Copyright 1996 John M. Danskin 7/30/96//// Permission is granted to use this software for any purpose as// long as this notice stays attached to this software.//#include <math.h>#include <stdlib.h>#include <iostream.h>#include <iomanip.h>#include <assert.h>#include <math.h>#include "global.hh"#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 0Real iHistogram::Entropy(int sym){    return -log(Count(sym)/(Real)totalCount) * onelog2;}#endifvoid 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 0int iHistogram::Count(int sym){    assert((sym >= 0) && (sym < nsyms));    return count[symToPos[sym]];}#endifvoid 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 + -