Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Entropy3d #101

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,13 @@ set(SOURCES
src/Algo2DEntropy.cc
src/Algo2DFourColors.cc
src/Algo2DGrayscale.cc

src/Algo3DCubeFull.cc
src/Algo3DCubeContiBnW.cc
src/Algo3DCubeContiRainbow.cc
src/Algo3DCubeContiFrebet.cc
src/Algo3DCubeEntropy.cc

src/Algo3DSphereFull.cc
src/Algo3DSphereContiBnW.cc
src/Algo3DSphereContiRainbow.cc
Expand Down
70 changes: 70 additions & 0 deletions src/Algo3DCubeEntropy.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#include <cmath>
#include <vector>
#include <iostream>

#include <Algo3DCubeEntropy.hh>

// github.com/cortesi/scurve/blob/a59e8335c48a7cda7043fbd1b28bcae1abc9645d/binvis#L58

inline float
entropy (const u8* data, size_t len, size_t offset, size_t blocksize=32, size_t n_symbols=256) {
if (len < blocksize)
throw std::range_error("Data length must be larger than block size.");

size_t start;
const auto half_block = blocksize / 2;
if (offset < half_block)
start = 0;
else if (offset > len - half_block)
start = len - half_block;
else
start = offset - half_block;

std::vector<float> hist(n_symbols, 0.0f);
for (size_t i = start; i < start + blocksize; ++i)
hist[ data[i] ]++;

auto Blocksize = static_cast<float>(blocksize);
auto base = static_cast<float>(std::min(blocksize, n_symbols));
auto base_log = 1 / std::log(base);
float entropy = 0;
for (float value : hist) {
if (value < 1.0f)
continue;
float p = value / Blocksize;
// If blocksize < 256, the number of possible byte values is restricted.
// In that case, we adjust the log base to make sure we get a value
// between 0 and 1.
entropy += p * std::log(p) * base_log;
}
return - entropy;
}

inline float
curve (float v) {
float f = std::pow(4 * (v - std::pow(v, 2)), 4);
return std::max(f, 0.0f);
}

bool
Algo3DCubeEntropy::apply(GLfloat* vertices, GLfloat* colors, VertIndices& selected,
size_t width, size_t height, size_t depth) {
make_vertices(vertices, width, height, depth);

const size_t chunk_size = width * height * 2;
const u8* read = loader_->dataChunk(0, chunk_size);
size_t pos = 0;
for (size_t i = 0; i < chunk_size; ++i) {
auto e = entropy(read, chunk_size, i, 32, 256);
float r = (e > 0.5f) ? curve(e - 0.5f) : 0.0f;
if (r > 0.0f)
selected.push_back(pos / 4);
float b = std::pow(e, 2);
colors[pos++] = r;
colors[pos++] = 0.0f;
colors[pos++] = b;
colors[pos++] = 1.0f;
}

return true;
}
4 changes: 4 additions & 0 deletions src/Algorithm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <Algo3DCubeContiBnW.hh>
#include <Algo3DCubeContiRainbow.hh>
#include <Algo3DCubeContiFrebet.hh>
#include <Algo3DCubeEntropy.hh>
#include <Algo3DSphereFull.hh>
#include <Algo3DSphereContiBnW.hh>
#include <Algo3DSphereContiRainbow.hh>
Expand Down Expand Up @@ -64,10 +65,13 @@ const std::map<const std::string, AlgorithmFactoryFunc> algorithms = {
{ "entropy", []() { return new Algo2DEntropy(); } },
{ "4col", []() { return new Algo2DFourColors(); } },
{ "gray", []() { return new Algo2DGrayscale(); } },

{ "cube", []() { return new Algo3DCubeFull(); } },
{ "contibnw", []() { return new Algo3DCubeContiBnW(); } },
{ "contirb", []() { return new Algo3DCubeContiRainbow(); } },
{ "conti", []() { return new Algo3DCubeContiFrebet(); } },
{ "cube_entropy", []() { return new Algo3DCubeEntropy(); } },

{ "sphere", []() { return new Algo3DSphereFull(); } },
{ "sphere_bnw", []() { return new Algo3DSphereContiBnW(); } },
{ "sphere_rb", []() { return new Algo3DSphereContiRainbow(); } },
Expand Down
2 changes: 2 additions & 0 deletions src/MmapLoader.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <iostream>

#include <MmapLoader.hh>

Expand Down Expand Up @@ -44,6 +45,7 @@ MmapFileLoader::data()
const u8*
MmapFileLoader::dataChunk(size_t offset, size_t size)
{
std::cout << size_ << " >= " << offset + size << std::endl;
if (size_ < offset + size)
throw std::out_of_range("Trying to read data out of bound");
return data() + offset;
Expand Down
13 changes: 13 additions & 0 deletions src/include/Algo3DCubeEntropy.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

#include <Algo3DCube.hh>

class Algo3DCubeEntropy : public Algo3DCube {
public:
Algo3DCubeEntropy() {}
virtual ~Algo3DCubeEntropy() {}

virtual bool apply(GLfloat* vertices, GLfloat* colors, VertIndices& selected,
size_t width, size_t height, size_t depth);
};