/*******************************************************************************
*
* McStas, neutron ray-tracing package
* Copyright 1997-2002, All rights reserved
* Risoe National Laboratory, Roskilde, Denmark
* Institut Laue Langevin, Grenoble, France
*
* Library: share/adapt_tree-lib.c
*
* %Identification
* Written by: KN, EF
* Date: Sep 02, 2002
* Origin: Risoe/ILL
* Release: McStas 1.6
* Version: $Revision: 1.7 $
*
* This file is to be imported by components handling adaptative trees, like
* Source_adapt and Adapt_check (in lib/sources)
* Embedded within instrument in runtime mode.
*
* Usage: within SHARE
* %include "adapt_tree-lib"
*
* $Id: adapt_tree-lib.c,v 1.7 2005/07/25 14:55:08 farhi Exp $
*
* $Log: adapt_tree-lib.c,v $
* Revision 1.7 2005/07/25 14:55:08 farhi
* DOC update:
* checked all parameter [unit] + text to be OK
* set all versions to CVS Revision
*
* Revision 1.6 2003/02/11 12:28:46 farhi
* Variouxs bug fixes after tests in the lib directory
* mcstas_r : disable output with --no-out.. flag. Fix 1D McStas output
* read_table:corrected MC_SYS_DIR -> MCSTAS define
* monitor_nd-lib: fix Log(signal) log(coord)
* HOPG.trm: reduce 4000 points -> 400 which is enough and faster to resample
* Progress_bar: precent -> percent parameter
* CS: ----------------------------------------------------------------------
*
* Revision 1.1 2002/09/02 18:59:05 ef
* Initial revision extracted from mcstas-r.c/h
*******************************************************************************/
#ifndef ADAPT_TREE_LIB_H
#error McStas : please import this library with %include "adapt_tree-lib"
#endif
/*******************************************************************************
* Find i in adaptive search tree t s.t. v(i) <= v < v(i+1).
*******************************************************************************/
int
adapt_tree_search(struct adapt_tree *t, adapt_t v)
{
adapt_t F = 0; /* Current value. */
int i = 0; /* Current candidate. */
int step = t->initstep;
adapt_t *s = t->s;
int j;
for(j = t->root; step > 0; step >>= 1)
{
F += s[j]; /* Cumulative value in current node */
if(v < F)
j -= step; /* Value is to the left or above. */
else
i = j, j += step; /* Value is current or to the right. */
}
/* Now j is at the bottom of a tree (a leaf node). */
if(v < F + s[j])
return i;
else
return j;
}
/*******************************************************************************
* Add v to v[i], updating the cumulative sums appropriately.
*******************************************************************************/
void
adapt_tree_add(struct adapt_tree *t, int i, adapt_t v)
{
int j = t->root;
int step = t->initstep;
adapt_t *s = t->s;
t->total += v;
t->v[i++] += v;
for(;;)
{
while(j < i)
j += step, step >>= 1;
s[j] += v;
while(j > i)
j -= step, step >>= 1;
if(j == i)
break;
s[j] -= v;
}
if(step)
s[j - step] -= v;
}
/*******************************************************************************
* Initialise an adaptive search tree. The tree has N nodes, and all nodes are
* initialized to zero. Any N > 0 is allowed, but is rounded up to the nearest
* value of the form N = 2**k - 2.
*******************************************************************************/
struct adapt_tree *
adapt_tree_init(int N)
{
struct adapt_tree *t;
int i;
int depth;
/* Round up to nearest 2**k - 2 */
for(depth = 0; ((1 << (depth + 1)) - 2) < N; depth++);
N = (1 << (depth + 1)) - 2;
t = malloc(sizeof(*t));
if(t)
{
t->s = malloc((N + 1) * sizeof(*(t->s)));
t->v = malloc(N * sizeof(*(t->v)));
}
if(!(t && t->s && t->v))
{
fprintf(stderr, "Error: Out of memory (adapt_tree_init).\n");
exit(1);
}
t->N = N;
t->depth = depth;
t->root = (1 << t->depth) - 1;
t->initstep = (1 << (t->depth - 1));
for(i = 0; i < t->N; i++)
{
t->s[i] = 0.0;
t->v[i] = 0.0;
}
t->s[i] = 0.0;
t->total = 0.0;
return t;
}
/*******************************************************************************
* Free memory allocated to an adaptive search tree.
*******************************************************************************/
void
adapt_tree_free(struct adapt_tree *t)
{
free(t->v);
free(t->s);
free(t);
}
/* end of adapt_tree-lib.c */
syntax highlighted by Code2HTML, v. 0.9.1