#include "utils/commons.h"
#include "heatmap.h"
#define HEATMAP_INT_MIN INT_MIN
#define HEATMAP_INT_MAX INT_MAX
#define HEATMAP_SEPARATOR ','
heatmap_t* heatmap_new(
const heatmap_type type,
const int min_v,
const int max_v,
const int min_h,
const int max_h,
const int resolution_points) {
heatmap_t* const heatmap = (heatmap_t*)malloc(sizeof(heatmap_t));
heatmap->type = type;
heatmap->min_v = min_v;
heatmap->max_v = max_v;
heatmap->min_h = min_h;
heatmap->max_h = max_h;
const int v_range = (max_v-min_v+1);
const int h_range = (max_h-min_h+1);
const int max_range = MAX(v_range,h_range);
if (max_range <= resolution_points) {
heatmap->binning_factor = 1.0f;
heatmap->num_rows = v_range;
heatmap->num_columns = h_range;
} else {
heatmap->binning_factor = (float)max_range/(float)resolution_points;
heatmap->num_rows = (float)v_range/heatmap->binning_factor;
heatmap->num_columns = (float)h_range/heatmap->binning_factor;
}
heatmap->values = (int**)malloc(heatmap->num_rows*sizeof(int*));
int i;
for (i=0;i<heatmap->num_rows;++i) {
heatmap->values[i] = (int*)malloc(heatmap->num_columns*sizeof(int)); }
heatmap_clear(heatmap);
return heatmap;
}
void heatmap_clear(
heatmap_t* const heatmap) {
const heatmap_type type = heatmap->type;
const int num_rows = heatmap->num_rows;
const int num_columns = heatmap->num_columns;
int i, j;
for (i=0;i<num_rows;++i) {
switch (type) {
case heatmap_min: {
for (j=0;j<num_columns;++j) heatmap->values[i][j] = HEATMAP_INT_MAX;
break;
}
case heatmap_max:
case heatmap_value:
default: {
for (j=0;j<num_columns;++j) heatmap->values[i][j] = HEATMAP_INT_MIN;
break;
}
}
}
}
void heatmap_delete(
heatmap_t* const heatmap) {
int i;
for (i=0;i<heatmap->num_rows;++i) {
free(heatmap->values[i]);
}
free(heatmap->values);
free(heatmap);
}
void heatmap_set(
heatmap_t* const heatmap,
const int v,
const int h,
const int value) {
const int num_rows = heatmap->num_rows;
const int num_columns = heatmap->num_columns;
if (v<heatmap->min_v || v>heatmap->max_v) return;
if (h<heatmap->min_h || h>heatmap->max_h) return;
int v_adjusted = (float)(v - heatmap->min_v) / heatmap->binning_factor;
int h_adjusted = (float)(h - heatmap->min_h) / heatmap->binning_factor;
if (v_adjusted >= num_rows) v_adjusted = num_rows-1;
if (h_adjusted >= num_columns) h_adjusted = num_columns-1;
switch (heatmap->type) {
case heatmap_min:
heatmap->values[v_adjusted][h_adjusted] = MIN(heatmap->values[v_adjusted][h_adjusted],value);
break;
case heatmap_max:
heatmap->values[v_adjusted][h_adjusted] = MAX(heatmap->values[v_adjusted][h_adjusted],value);
break;
case heatmap_value:
default:
heatmap->values[v_adjusted][h_adjusted] = value;
break;
}
}
void heatmap_print(
FILE* const stream,
heatmap_t* const heatmap) {
const int num_rows = heatmap->num_rows;
const int num_columns = heatmap->num_columns;
int v, h;
for (v=0;v<num_rows;++v) {
for (h=0;h<num_columns;++h) {
if (h>0) fprintf(stream,"%c",HEATMAP_SEPARATOR);
const int value = heatmap->values[v][h];
if (value == HEATMAP_INT_MIN || value == HEATMAP_INT_MAX) {
fprintf(stream,"-1");
} else {
fprintf(stream,"%d",value);
}
}
fprintf(stream,"\n");
}
}