Packages
mmath
0.2.3
0.2.26
0.2.25
0.2.24
0.2.23
0.2.22
0.2.21
0.2.20
0.2.19
0.2.18
0.2.17
0.2.16
0.2.15
0.2.14
0.2.13
0.2.12
0.2.11
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.2.0-alpha9
0.2.0-alpha8
0.2.0-alpha7
0.2.0-alpha6
0.2.0-alpha5
0.2.0-alpha4
0.2.0-alpha3
0.2.0-alpha2
0.2.0-alpha10
0.2.0-alpha1
0.2.0-alpha
0.1.17-alpha
0.1.16
0.1.15
0.1.14
0.1.13
0.1.11
0.1.10
0.1.9
0.1.8
0.1.7
0.1.6
math library for metric sequences and binary arrays.
Current section
Files
Jump to
Current section
Files
c_src/aggr_nif.c
#include "erl_nif.h"
#include "mmath.h"
#include <math.h>
static int
load(ErlNifEnv* env, void** priv, ERL_NIF_TERM load_info)
{
return 0;
}
static int
upgrade(ErlNifEnv* env, void** priv, void** old_priv, ERL_NIF_TERM load_info)
{
return 0;
}
static ERL_NIF_TERM
min(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifBinary bin;
ERL_NIF_TERM r;
ffloat* vs;
ffloat* target;
ErlNifSInt64 chunk; // size to be compressed
uint64_t target_i = 0; // target position
ffloat aggr; // target position
double confidence;
uint32_t pos;
uint32_t count;
uint32_t target_size;
if (argc != 2)
return enif_make_badarg(env);
GET_CHUNK(chunk);
GET_BIN(0, bin, count, vs);
target_size = ceil((double) count / chunk) * sizeof(ffloat);
if (! (target = (ffloat*) enif_make_new_binary(env, target_size, &r)))
return enif_make_badarg(env); // TODO return propper error
// If we don't have any input data we can return right away.
if (count == 0)
return r;
// We know we have at least one element in the list so our
// aggregator will start with this
aggr = vs[0];
confidence = aggr.confidence;
pos = 1;
// We itterate over the remining i .. count-1 elements
for (uint32_t i = 1; i < count; i++, pos++) {
if (pos == chunk) {
aggr.confidence = confidence / chunk;
target[target_i] = aggr;
target_i++;
aggr = vs[i];
confidence = aggr.confidence;
pos = 0;
} else {
confidence += vs[i].confidence;
if (vs[i].value < aggr.value) {
aggr = vs[i];
};
}
}
// Making sure the last aggregate is saved.
if (target_i < target_size) {
// We use chunk here to reflect the additional loss
// in certenty of not computing a whole chunk.
aggr.confidence = confidence / chunk;
target[target_i] = aggr;
}
return r;
}
static ERL_NIF_TERM
max(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifBinary bin;
ERL_NIF_TERM r;
ffloat* vs;
ffloat* target;
ErlNifSInt64 chunk; // size to be compressed
ErlNifSInt64 target_i = 0; // target position
ffloat aggr; // target position
double confidence = 0;
uint32_t pos;
uint32_t count;
uint32_t target_size;
if (argc != 2)
return enif_make_badarg(env);
GET_CHUNK(chunk);
GET_BIN(0, bin, count, vs);
target_size = ceil((double) count / chunk) * sizeof(ffloat);
if (! (target = (ffloat*) enif_make_new_binary(env, target_size, &r)))
return enif_make_badarg(env); // TODO return propper error
// If we don't have any input data we can return right away.
if (count == 0)
return r;
// We know we have at least one element in the list so our
// aggregator will start with this
aggr = vs[0];
confidence = aggr.confidence;
pos = 1;
// We itterate over the remining i .. count-1 elements
for (uint32_t i = 1; i < count; i++, pos++) {
if (pos == chunk) {
aggr.confidence = confidence / chunk;
target[target_i] = aggr;
target_i++;
aggr = vs[i];
confidence = aggr.confidence;
pos = 0;
} else {
confidence += vs[i].confidence;
if (vs[i].value > aggr.value) {
aggr = vs[i];
};
}
}
// Making sure the last aggregate is saved.
if (target_i < target_size) {
// We use chunk here to reflect the additional loss
// in certenty of not computing a whole chunk.
aggr.confidence = confidence / chunk;
target[target_i] = aggr;
}
return r;
}
static ERL_NIF_TERM
sum(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifBinary bin;
ErlNifSInt64 chunk; // size to be compressed
ERL_NIF_TERM r;
ffloat* vs;
ffloat* target;
ffloat aggr; // Aggregator
double confidence;
uint32_t target_i = 0; // target position
uint32_t count;
uint32_t pos = 0;
uint32_t target_size;
if (argc != 2)
return enif_make_badarg(env);
GET_CHUNK(chunk);
GET_BIN(0, bin, count, vs);
target_size = ceil((double) count / chunk) * sizeof(ffloat);
if (! (target = (ffloat*) enif_make_new_binary(env, target_size, &r)))
return enif_make_badarg(env); // TODO return propper error
if (count > 0) {
aggr = vs[0];
confidence = aggr.confidence;
pos = 1;
//We will be overwriting the confidence generated by dec_add because
//it would give a false impression based on the later values having
//a higher influence.
for (uint32_t i = 1; i < count; i++, pos++) {
if (pos == chunk) {
aggr.confidence = confidence / chunk;
target[target_i] = aggr;
target_i++;
aggr = vs[i];
confidence = aggr.confidence;
pos = 0;
} else {
confidence += vs[i].confidence;
aggr.value += vs[i].value;
}
}
if (count % chunk) {
aggr = float_add(aggr, float_mul(vs[count - 1], (chunk - (count % chunk))));
}
aggr.confidence = confidence / chunk;
target[target_i] = aggr;
}
return r;
}
static ERL_NIF_TERM
avg(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifBinary bin;
ERL_NIF_TERM r;
ffloat* vs;
ffloat* target;
ErlNifSInt64 chunk; // size to be compressed
ffloat aggr; // Aggregator
double confidence;
uint32_t target_i = 0; // target position
uint32_t count;
uint32_t pos = 0;
uint32_t target_size;
if (argc != 2)
return enif_make_badarg(env);
GET_CHUNK(chunk);
GET_BIN(0, bin, count, vs);
target_size = ceil((double) count / chunk) * sizeof(ffloat);
if (! (target = (ffloat*) enif_make_new_binary(env, target_size, &r)))
return enif_make_badarg(env); // TODO return propper error
if (count == 0)
return r;
aggr = vs[0];
confidence = aggr.confidence;
pos++;
for (uint32_t i = 1; i < count; i++, pos++) {
if (pos == chunk) {
aggr.confidence = confidence / chunk;
target[target_i] = float_div(aggr, chunk);
target_i++;
aggr = vs[i];
confidence = aggr.confidence;
pos = 0;
} else {
confidence += vs[i].confidence;
aggr = float_add(aggr, vs[i]);
}
}
if (count % chunk) {
aggr = float_add(aggr, float_mul(vs[count - 1], (chunk - (count % chunk))));
}
aggr.confidence = confidence / chunk;
target[target_i] = float_div(aggr, chunk);
return r;
}
static ErlNifFunc nif_funcs[] = {
{"min", 2, min},
{"max", 2, max},
{"sum", 2, sum},
{"avg", 2, avg}
};
// Initialize this NIF library.
//
// Args: (MODULE, ErlNifFunc funcs[], load, reload, upgrade, unload)
// Docs: http://erlang.org/doc/man/erl_nif.html#ERL_NIF_INIT
ERL_NIF_INIT(mmath_aggr, nif_funcs, &load, NULL, &upgrade, NULL);