<commit_before>#include <stdlib.h>
#include <string.h>

#include "muwave.h"

// TODO: only define the ARRAY_LENGTH macro conditionally
#define ARRAY_LENGTH(array) (sizeof((array))/sizeof((array)[0]))

/* Creation and deletion of muwave state objects. */
muwave_state *muwave_generatestate(int dimensions, int window_size) {

    size_t internal_size = sizeof(muwave_state);

    muwave_state *state = (muwave_state *) malloc(internal_size);
    memset(state, 0, internal_size);
    state->error_bit = false;
    state->dimensions = dimensions;
    state->window_size = window_size > 0 ? window_size : 2;
    return state;
}

void muwave_destroy_gesture(muwave_gesture *gesture) {
    if (gesture == NULL) {
        return;
    }
    // TODO: free more than just this.
    free(gesture);
    gesture = NULL;
}

void muwave_destroy_state(muwave_state *state) {
    if (state == NULL) { return; }
    /* TODO: remove all additional fields inside the muwave_state variable */
    for (int i=0; i<state->num_gestures_saved; ++i) {
        muwave_destroy_gesture(state->gestures[i]);
    }
    free(state);
    state = NULL;
}

int muwave_start_record_gesture(muwave_state *state) {
    if (state->num_gestures_saved != 0) {
        state->gestures = (muwave_gesture **)realloc(state->gestures, (state->num_gestures_saved + 1)*sizeof(muwave_gesture *));
    } else {
        state->gestures = (muwave_gesture **)malloc(sizeof(muwave_gesture *));
    }
    int gesture_id = ++state->num_gestures_saved;

    size_t gesture_size = sizeof(muwave_gesture);
    state->gestures[gesture_id] = malloc(gesture_size);
    memset(state->gestures[gesture_id], 0, gesture_size);
    state->gestures[gesture_id]->is_recording = true;
    state->gestures[gesture_id]->is_recorded = false;
    return gesture_id;
}

// TODO: adjust the hand-tuned utility function using params from the uWave algorithm
int normalize(int sum) {
    if (sum > 20) {
        return 15;
    } else if (sum > 10) {
        return (sum-10)*5.0+10;
    } else if (sum > -10) {
        return sum;
    } else if (sum > -20) {
        return (sum+10)*5.0-10;
    } else { // sum <= -20
        return -15;
    }
}

// TODO: does this work for zero recorded timestamps?
void muwave_end_record_gesture(muwave_state *state, int gesture_id) {
    // TODO: Check with a macro for error bit, nullity with error logging.
    if (state == NULL) {return;}
    // TODO: use specific types in c instead of this stuff.
    if (gesture_id < 0) {return;}
    // TODO: complain about an invalid value.
    if (state->num_gestures_saved <= gesture_id) {return;}
    // TODO: use the assert library instead. This should never happen unless muwave doesn't have integrity.
    if (state->gestures[gesture_id] == NULL) {return;}
    // TODO: complain about this with a message.
    if (state->gestures[gesture_id]->is_recording) {return;}
    // TODO: use the assert library instead. This should never happen unless muwave doesn't have integrity.
    if (state->gestures[gesture_id]->is_recorded) {return;}

    muwave_gesture *gesture = state->gestures[gesture_id];
    gesture->is_recording = false;

    // allocate normalized array

    // TODO: verify if safe to divide and assume a round-down.
    int normalized_recording_len = gesture->recording_size - gesture->recording_size%state->window_size;
    normalized_recording_len = normalized_recording_len / state->window_size;

    gesture->normalized_recording = calloc(normalized_recording_len, sizeof(int*));

    // convert from raw to normalized
    for (int i=0; i<normalized_recording_len; ++i) {
        int16_t *sum = calloc(state->dimensions, sizeof(int16_t));
        int j_end = (i+1)*state->window_size;
        for (int j=i*state->window_size; j<=j_end; ++j) {
            for (int d=0; d<state->dimensions; ++d) {
                sum[d] += gesture->raw_recording[j][d];
            }
        }

        gesture->normalized_recording[i] = malloc(state->dimensions * sizeof(int));
        for (int d=0; d<state->dimensions; ++d) {
            gesture->normalized_recording[i][d] = normalize(sum[d]);
        }
    }

    // free raw
    for(i=0; i<gesture->recording_size; ++i) {
        free(gesture->raw_recording[i]);
        gesture->raw_recording[i] = NULL;<commit_msg>Implemented normalization with variable window size.<commit_after>#include <stdlib.h>
#include <string.h>

#include "muwave.h"

// TODO: include these from a header file?
#define MAX(a,b) \
   ({ __typeof__ (a) _a = (a); \
       __typeof__ (b) _b = (b); \
     _a > _b ? _a : _b; })
#define MIN(a,b) \
   ({ __typeof__ (a) _a = (a); \
       __typeof__ (b) _b = (b); \
     _a < _b ? _a : _b; })

// TODO: only define the ARRAY_LENGTH macro conditionally
#define ARRAY_LENGTH(array) (sizeof((array))/sizeof((array)[0]))

/* Creation and deletion of muwave state objects. */
muwave_state *muwave_generatestate(int dimensions, int window_size) {

    size_t internal_size = sizeof(muwave_state);

    muwave_state *state = (muwave_state *) malloc(internal_size);
    memset(state, 0, internal_size);
    state->error_bit = false;
    state->dimensions = dimensions;
    state->window_size = window_size > 0 ? window_size : 2;
    return state;
}

void muwave_destroy_gesture(muwave_gesture *gesture) {
    if (gesture == NULL) {
        return;
    }
    // TODO: free more than just this.
    free(gesture);
    gesture = NULL;
}

void muwave_destroy_state(muwave_state *state) {
    if (state == NULL) { return; }
    /* TODO: remove all additional fields inside the muwave_state variable */
    for (int i=0; i<state->num_gestures_saved; ++i) {
        muwave_destroy_gesture(state->gestures[i]);
    }
    free(state);
    state = NULL;
}

int muwave_start_record_gesture(muwave_state *state) {
    if (state->num_gestures_saved != 0) {
        state->gestures = (muwave_gesture **)realloc(state->gestures, (state->num_gestures_saved + 1)*sizeof(muwave_gesture *));
    } else {
        state->gestures = (muwave_gesture **)malloc(sizeof(muwave_gesture *));
    }
    int gesture_id = ++state->num_gestures_saved;

    size_t gesture_size = sizeof(muwave_gesture);
    state->gestures[gesture_id] = malloc(gesture_size);
    memset(state->gestures[gesture_id], 0, gesture_size);
    state->gestures[gesture_id]->is_recording = true;
    state->gestures[gesture_id]->is_recorded = false;
    return gesture_id;
}

// TODO: adjust the hand-tuned utility function using params from the uWave algorithm
int normalize(int sum) {
    if (sum > 20) {
        return 15;
    } else if (sum > 10) {
        return (sum-10)*5.0+10;
    } else if (sum > -10) {
        return sum;
    } else if (sum > -20) {
        return (sum+10)*5.0-10;
    } else { // sum <= -20
        return -15;
    }
}

// TODO: does this work for zero recorded timestamps?
void muwave_end_record_gesture(muwave_state *state, int gesture_id) {
    // TODO: Check with a macro for error bit, nullity with error logging.
    if (state == NULL) {return;}
    // TODO: use specific types in c instead of this stuff.
    if (gesture_id < 0) {return;}
    // TODO: complain about an invalid value.
    if (state->num_gestures_saved <= gesture_id) {return;}
    // TODO: use the assert library instead. This should never happen unless muwave doesn't have integrity.
    if (state->gestures[gesture_id] == NULL) {return;}
    // TODO: complain about this with a message.
    if (state->gestures[gesture_id]->is_recording) {return;}
    // TODO: use the assert library instead. This should never happen unless muwave doesn't have integrity.
    if (state->gestures[gesture_id]->is_recorded) {return;}

    muwave_gesture *gesture = state->gestures[gesture_id];
    gesture->is_recording = false;

    // allocate normalized array

    // TODO: verify if safe to divide and assume a round-down.
    int normalized_recording_len = gesture->recording_size - gesture->recording_size%state->window_size;
    normalized_recording_len = normalized_recording_len / state->window_size;

    gesture->normalized_recording = calloc(normalized_recording_len, sizeof(int*));

    // convert from raw to normalized
    // TODO: this can be done much more efficiently, re-implement once testing is up.
    for (int i=0; i<gesture->recording_size; ++i) {
        if (i%state->window_size != state->window_size-1) { continue; }
        int *sum = malloc(state->dimensions * sizeof(int));
        for (int d=0; d<state->dimensions; ++d) {
            int num_counted = 0;
            for (int j=MAX(0, i-state->window_size); j<i; ++j) {
                sum[d] += gesture->raw_recording[j][d];
                ++num_counted;
            }
            sum[d] /= num_counted;
            sum[d] = normalize(sum[d]);
        }
        int normalized_id = (i+1)/state->window_size;
        gesture->normalized_recording[normalized_id] = sum;
    }

    // free raw
    for(i=0; i<gesture->recording_size; ++i) {
        free(gesture->raw_recording[i]);
        gesture->raw_recording[i] = NULL;
{'fraction_non_alphanumeric': 0.1308981902964361, 'fraction_numerical': 0.00954812923281892, 'mean_word_length': 3.180046403712297, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 102, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1591184', 'n_tokens_mistral': 3041, 'n_tokens_neox': 2955, 'n_words': 737}