blob: 3348842762870a57bc168d5a4b72e98a17652c4f [file] [log] [blame]
/* AUTORIGHTS
Copyright (C) 2007 Princeton University
This file is part of Ferret Toolkit.
Ferret Toolkit is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <values.h>
#include <cass_stat.h>
#ifdef _OPENMP
#include <omp.h>
#endif
#define MAX_THREAD 32
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define MIN(a,b) ((a) < (b) ? (a) : (b))
void stat_init (stat_t *s)
{
stat_reset(s);
s->parallel = NULL;
}
void stat_cleanup (stat_t *s)
{
if (s->parallel != NULL) free(s->parallel);
}
void stat_pre_parallel (stat_t *s)
{
#ifdef _OPENMP
int i;
if (s->parallel == NULL)
{
s->parallel = (stat_t *)malloc(MAX_THREAD * sizeof(stat_t));
assert(s->parallel != NULL);
}
for (i = 0; i < MAX_THREAD; i++)
{
stat_reset(&s->parallel[i]);
}
#endif
}
void stat_post_parallel (stat_t *s)
{
#ifdef _OPENMP
int i;
for (i = 0; i < MAX_THREAD; i++)
{
if (s->parallel[i].cnt <= 0) continue;
s->cnt += s->parallel[i].cnt;
s->sum += s->parallel[i].sum;
s->sum2 += s->parallel[i].sum2;
s->max = MAX(s->max, s->parallel[i].max);
s->min = MIN(s->min, s->parallel[i].min);
}
#endif
}
void
stat_reset(stat_t *ret)
{
ret->sum = 0;
ret->sum2 = 0;
ret->cnt = 0;
ret->max = MINFLOAT;
ret->min = MAXFLOAT;
}
static inline void
_stat_insert(stat_t *s, float v)
{
s->min = MIN(s->min, v);
s->max = MAX(s->max, v);
s->sum += v;
s->sum2 += v * v;
s->cnt++;
}
void stat_insert(stat_t *s, float v)
{
#ifdef _OPENMP
if (omp_in_parallel())
{
int id = omp_get_thread_num();
assert(id < MAX_THREAD);
_stat_insert(&s->parallel[id], v);
}
else
#endif
{
_stat_insert(s, v);
}
}
float
stat_min(stat_t *s)
{
return s->min;
}
float
stat_max(stat_t *s)
{
return s->max;
}
float
stat_avg(stat_t *s)
{
if (s->cnt > 0)
return s->sum / s->cnt;
else
return 0;
}
float
stat_std(stat_t *s)
{
if (s->cnt > 1)
return sqrt((s->sum2 - (s->sum/s->cnt) * s->sum)/(s->cnt - 1));
else
return 0;
}
void
stat_print(stat_t *s, const char *msg)
{
if (msg)
printf("%s: ", msg);
printf("cnt=%d, min=%.3f, max=%.3f, avg=%.3f, std=%.3f\n",
s->cnt, s->min, s->max, stat_avg(s), stat_std(s));
}