2013-11-13 22:50:38 +04:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <math.h>
|
2014-11-19 00:51:04 +03:00
|
|
|
#include <float.h>
|
2015-01-13 04:27:08 +03:00
|
|
|
#include <limits.h>
|
2014-11-19 00:51:04 +03:00
|
|
|
|
|
|
|
#include "utils.h"
|
|
|
|
|
2015-01-23 03:38:24 +03:00
|
|
|
void pm(int M, int N, float *A)
|
|
|
|
{
|
|
|
|
int i,j;
|
|
|
|
for(i =0 ; i < M; ++i){
|
|
|
|
for(j = 0; j < N; ++j){
|
|
|
|
printf("%10.6f, ", A[i*N+j]);
|
|
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-11-19 00:51:04 +03:00
|
|
|
char *find_replace(char *str, char *orig, char *rep)
|
|
|
|
{
|
|
|
|
static char buffer[4096];
|
|
|
|
char *p;
|
|
|
|
|
|
|
|
if(!(p = strstr(str, orig))) // Is 'orig' even in 'str'?
|
|
|
|
return str;
|
|
|
|
|
|
|
|
strncpy(buffer, str, p-str); // Copy characters from 'str' start to 'orig' st$
|
|
|
|
buffer[p-str] = '\0';
|
|
|
|
|
|
|
|
sprintf(buffer+(p-str), "%s%s", rep, p+strlen(orig));
|
|
|
|
|
|
|
|
return buffer;
|
|
|
|
}
|
2013-11-13 22:50:38 +04:00
|
|
|
|
2014-10-22 01:49:18 +04:00
|
|
|
float sec(clock_t clocks)
|
|
|
|
{
|
|
|
|
return (float)clocks/CLOCKS_PER_SEC;
|
|
|
|
}
|
|
|
|
|
2014-11-19 00:51:04 +03:00
|
|
|
void top_k(float *a, int n, int k, int *index)
|
|
|
|
{
|
|
|
|
int i,j;
|
2014-12-12 00:15:26 +03:00
|
|
|
for(j = 0; j < k; ++j) index[j] = 0;
|
|
|
|
for(i = 0; i < n; ++i){
|
|
|
|
int curr = i;
|
|
|
|
for(j = 0; j < k; ++j){
|
|
|
|
if(a[curr] > a[index[j]]){
|
|
|
|
int swap = curr;
|
|
|
|
curr = index[j];
|
|
|
|
index[j] = swap;
|
2014-11-19 00:51:04 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-23 03:38:24 +03:00
|
|
|
void error(const char *s)
|
2013-11-13 22:50:38 +04:00
|
|
|
{
|
2014-12-07 11:41:26 +03:00
|
|
|
perror(s);
|
2013-11-13 22:50:38 +04:00
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void malloc_error()
|
|
|
|
{
|
|
|
|
fprintf(stderr, "Malloc error\n");
|
|
|
|
exit(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void file_error(char *s)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "Couldn't open file: %s\n", s);
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
list *split_str(char *s, char delim)
|
|
|
|
{
|
2015-01-13 04:27:08 +03:00
|
|
|
size_t i;
|
|
|
|
size_t len = strlen(s);
|
2013-11-13 22:50:38 +04:00
|
|
|
list *l = make_list();
|
|
|
|
list_insert(l, s);
|
|
|
|
for(i = 0; i < len; ++i){
|
|
|
|
if(s[i] == delim){
|
|
|
|
s[i] = '\0';
|
|
|
|
list_insert(l, &(s[i+1]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return l;
|
|
|
|
}
|
|
|
|
|
|
|
|
void strip(char *s)
|
|
|
|
{
|
2015-01-13 04:27:08 +03:00
|
|
|
size_t i;
|
|
|
|
size_t len = strlen(s);
|
|
|
|
size_t offset = 0;
|
2013-11-13 22:50:38 +04:00
|
|
|
for(i = 0; i < len; ++i){
|
|
|
|
char c = s[i];
|
|
|
|
if(c==' '||c=='\t'||c=='\n') ++offset;
|
|
|
|
else s[i-offset] = c;
|
|
|
|
}
|
|
|
|
s[len-offset] = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
void strip_char(char *s, char bad)
|
|
|
|
{
|
2015-01-13 04:27:08 +03:00
|
|
|
size_t i;
|
|
|
|
size_t len = strlen(s);
|
|
|
|
size_t offset = 0;
|
2013-11-13 22:50:38 +04:00
|
|
|
for(i = 0; i < len; ++i){
|
|
|
|
char c = s[i];
|
|
|
|
if(c==bad) ++offset;
|
|
|
|
else s[i-offset] = c;
|
|
|
|
}
|
|
|
|
s[len-offset] = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
char *fgetl(FILE *fp)
|
|
|
|
{
|
|
|
|
if(feof(fp)) return 0;
|
2014-12-28 20:42:35 +03:00
|
|
|
size_t size = 512;
|
2013-11-13 22:50:38 +04:00
|
|
|
char *line = malloc(size*sizeof(char));
|
|
|
|
if(!fgets(line, size, fp)){
|
|
|
|
free(line);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-12-28 20:42:35 +03:00
|
|
|
size_t curr = strlen(line);
|
2014-11-19 00:51:04 +03:00
|
|
|
|
2014-12-28 20:42:35 +03:00
|
|
|
while((line[curr-1] != '\n') && !feof(fp)){
|
2015-01-13 04:27:08 +03:00
|
|
|
if(curr == size-1){
|
|
|
|
size *= 2;
|
|
|
|
line = realloc(line, size*sizeof(char));
|
|
|
|
if(!line) {
|
|
|
|
printf("%ld\n", size);
|
|
|
|
malloc_error();
|
|
|
|
}
|
2014-10-28 05:45:06 +03:00
|
|
|
}
|
2015-01-13 04:27:08 +03:00
|
|
|
size_t readsize = size-curr;
|
|
|
|
if(readsize > INT_MAX) readsize = INT_MAX-1;
|
|
|
|
fgets(&line[curr], readsize, fp);
|
2013-11-13 22:50:38 +04:00
|
|
|
curr = strlen(line);
|
|
|
|
}
|
2014-12-28 20:42:35 +03:00
|
|
|
if(line[curr-1] == '\n') line[curr-1] = '\0';
|
2013-11-13 22:50:38 +04:00
|
|
|
|
|
|
|
return line;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *copy_string(char *s)
|
|
|
|
{
|
|
|
|
char *copy = malloc(strlen(s)+1);
|
|
|
|
strncpy(copy, s, strlen(s)+1);
|
|
|
|
return copy;
|
|
|
|
}
|
|
|
|
|
|
|
|
list *parse_csv_line(char *line)
|
|
|
|
{
|
|
|
|
list *l = make_list();
|
|
|
|
char *c, *p;
|
|
|
|
int in = 0;
|
|
|
|
for(c = line, p = line; *c != '\0'; ++c){
|
|
|
|
if(*c == '"') in = !in;
|
|
|
|
else if(*c == ',' && !in){
|
|
|
|
*c = '\0';
|
|
|
|
list_insert(l, copy_string(p));
|
|
|
|
p = c+1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
list_insert(l, copy_string(p));
|
|
|
|
return l;
|
|
|
|
}
|
|
|
|
|
|
|
|
int count_fields(char *line)
|
|
|
|
{
|
2014-11-19 00:51:04 +03:00
|
|
|
int count = 0;
|
|
|
|
int done = 0;
|
2013-11-13 22:50:38 +04:00
|
|
|
char *c;
|
2014-11-19 00:51:04 +03:00
|
|
|
for(c = line; !done; ++c){
|
|
|
|
done = (*c == '\0');
|
|
|
|
if(*c == ',' || done) ++count;
|
|
|
|
}
|
|
|
|
return count;
|
2013-11-13 22:50:38 +04:00
|
|
|
}
|
|
|
|
|
2014-01-29 04:28:42 +04:00
|
|
|
float *parse_fields(char *line, int n)
|
2013-11-13 22:50:38 +04:00
|
|
|
{
|
2014-11-19 00:51:04 +03:00
|
|
|
float *field = calloc(n, sizeof(float));
|
|
|
|
char *c, *p, *end;
|
|
|
|
int count = 0;
|
|
|
|
int done = 0;
|
|
|
|
for(c = line, p = line; !done; ++c){
|
|
|
|
done = (*c == '\0');
|
|
|
|
if(*c == ',' || done){
|
|
|
|
*c = '\0';
|
|
|
|
field[count] = strtod(p, &end);
|
|
|
|
if(p == c) field[count] = nan("");
|
|
|
|
if(end != c && (end != c-1 || *end != '\r')) field[count] = nan(""); //DOS file formats!
|
|
|
|
p = c+1;
|
|
|
|
++count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return field;
|
2013-11-13 22:50:38 +04:00
|
|
|
}
|
|
|
|
|
2014-08-11 23:52:07 +04:00
|
|
|
float sum_array(float *a, int n)
|
2013-12-03 04:41:40 +04:00
|
|
|
{
|
|
|
|
int i;
|
2014-01-29 04:28:42 +04:00
|
|
|
float sum = 0;
|
2013-12-03 04:41:40 +04:00
|
|
|
for(i = 0; i < n; ++i) sum += a[i];
|
2014-08-11 23:52:07 +04:00
|
|
|
return sum;
|
|
|
|
}
|
|
|
|
|
|
|
|
float mean_array(float *a, int n)
|
|
|
|
{
|
|
|
|
return sum_array(a,n)/n;
|
2013-12-03 04:41:40 +04:00
|
|
|
}
|
2013-11-13 22:50:38 +04:00
|
|
|
|
2014-01-29 04:28:42 +04:00
|
|
|
float variance_array(float *a, int n)
|
2013-12-03 04:41:40 +04:00
|
|
|
{
|
|
|
|
int i;
|
2014-01-29 04:28:42 +04:00
|
|
|
float sum = 0;
|
|
|
|
float mean = mean_array(a, n);
|
2013-12-03 04:41:40 +04:00
|
|
|
for(i = 0; i < n; ++i) sum += (a[i] - mean)*(a[i]-mean);
|
2014-01-29 04:28:42 +04:00
|
|
|
float variance = sum/n;
|
2013-12-03 04:41:40 +04:00
|
|
|
return variance;
|
|
|
|
}
|
|
|
|
|
2014-01-29 04:28:42 +04:00
|
|
|
float constrain(float a, float max)
|
2013-12-03 04:41:40 +04:00
|
|
|
{
|
|
|
|
if(a > abs(max)) return abs(max);
|
|
|
|
if(a < -abs(max)) return -abs(max);
|
|
|
|
return a;
|
|
|
|
}
|
2013-11-13 22:50:38 +04:00
|
|
|
|
2014-01-29 04:28:42 +04:00
|
|
|
void normalize_array(float *a, int n)
|
2013-12-03 04:41:40 +04:00
|
|
|
{
|
|
|
|
int i;
|
2014-01-29 04:28:42 +04:00
|
|
|
float mu = mean_array(a,n);
|
|
|
|
float sigma = sqrt(variance_array(a,n));
|
2013-12-03 04:41:40 +04:00
|
|
|
for(i = 0; i < n; ++i){
|
|
|
|
a[i] = (a[i] - mu)/sigma;
|
|
|
|
}
|
|
|
|
mu = mean_array(a,n);
|
|
|
|
sigma = sqrt(variance_array(a,n));
|
|
|
|
}
|
|
|
|
|
2014-01-29 04:28:42 +04:00
|
|
|
void translate_array(float *a, int n, float s)
|
2013-12-06 01:17:16 +04:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for(i = 0; i < n; ++i){
|
|
|
|
a[i] += s;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-29 04:28:42 +04:00
|
|
|
void scale_array(float *a, int n, float s)
|
2013-12-06 01:17:16 +04:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for(i = 0; i < n; ++i){
|
|
|
|
a[i] *= s;
|
|
|
|
}
|
|
|
|
}
|
2014-12-18 22:28:42 +03:00
|
|
|
|
2014-01-29 04:28:42 +04:00
|
|
|
int max_index(float *a, int n)
|
2013-12-06 01:17:16 +04:00
|
|
|
{
|
|
|
|
if(n <= 0) return -1;
|
|
|
|
int i, max_i = 0;
|
2014-01-29 04:28:42 +04:00
|
|
|
float max = a[0];
|
2013-12-06 01:17:16 +04:00
|
|
|
for(i = 1; i < n; ++i){
|
|
|
|
if(a[i] > max){
|
|
|
|
max = a[i];
|
|
|
|
max_i = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return max_i;
|
|
|
|
}
|
|
|
|
|
2014-12-12 00:15:26 +03:00
|
|
|
// From http://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform
|
|
|
|
#define TWO_PI 6.2831853071795864769252866
|
2014-01-29 04:28:42 +04:00
|
|
|
float rand_normal()
|
2013-12-03 04:41:40 +04:00
|
|
|
{
|
2014-12-12 00:15:26 +03:00
|
|
|
static int haveSpare = 0;
|
|
|
|
static double rand1, rand2;
|
|
|
|
|
|
|
|
if(haveSpare)
|
|
|
|
{
|
|
|
|
haveSpare = 0;
|
|
|
|
return sqrt(rand1) * sin(rand2);
|
|
|
|
}
|
|
|
|
|
|
|
|
haveSpare = 1;
|
|
|
|
|
|
|
|
rand1 = rand() / ((double) RAND_MAX);
|
|
|
|
if(rand1 < 1e-100) rand1 = 1e-100;
|
|
|
|
rand1 = -2 * log(rand1);
|
|
|
|
rand2 = (rand() / ((double) RAND_MAX)) * TWO_PI;
|
|
|
|
|
|
|
|
return sqrt(rand1) * cos(rand2);
|
2013-12-03 04:41:40 +04:00
|
|
|
}
|
2014-12-12 00:15:26 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
float rand_normal()
|
|
|
|
{
|
|
|
|
int n = 12;
|
|
|
|
int i;
|
|
|
|
float sum= 0;
|
|
|
|
for(i = 0; i < n; ++i) sum += (float)rand()/RAND_MAX;
|
|
|
|
return sum-n/2.;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
2014-02-14 22:26:31 +04:00
|
|
|
float rand_uniform()
|
|
|
|
{
|
|
|
|
return (float)rand()/RAND_MAX;
|
|
|
|
}
|
2013-12-07 01:26:09 +04:00
|
|
|
|
2014-01-29 04:28:42 +04:00
|
|
|
float **one_hot_encode(float *a, int n, int k)
|
2013-12-07 01:26:09 +04:00
|
|
|
{
|
|
|
|
int i;
|
2014-01-29 04:28:42 +04:00
|
|
|
float **t = calloc(n, sizeof(float*));
|
2013-12-07 01:26:09 +04:00
|
|
|
for(i = 0; i < n; ++i){
|
2014-01-29 04:28:42 +04:00
|
|
|
t[i] = calloc(k, sizeof(float));
|
2013-12-07 01:26:09 +04:00
|
|
|
int index = (int)a[i];
|
|
|
|
t[i][index] = 1;
|
|
|
|
}
|
|
|
|
return t;
|
|
|
|
}
|
|
|
|
|