ftp.nice.ch/pub/next/science/mathematics/hippoplotamus.2.0.s.tar.gz#/hippo2.0/hntuple.c

This is hntuple.c in view mode; [Download] [Up]

/*
 * hippo.c - histogramming package in C. 
 *
 * Copyright (C)  1991  The Board of Trustees of The Leland Stanford
 * Junior University.  All Rights Reserved.
 *
 * $Id: hntuple.c,v 5.0 1993/08/17 21:55:18 rensing Exp $
 *
 * by jonas karlsson, at SLAC, August 1990
 *  split up by Paul Rensing, Feb 28,1991
 */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/* on SGI FLT_MIN, FLT_MAX are in limits.h also */
#ifndef sgi
#include <float.h>
#endif
#include <limits.h>
#include <string.h>
#include "hippo.h"

GLOB_QUAL const char hippontuple_c_rcsid[] = 
     "$Id: hntuple.c,v 5.0 1993/08/17 21:55:18 rensing Exp $";
GLOB_QUAL const char hippo_h_rcsid[] = HIPPO_H_RCSID;

/*
 * number of floats allocated for a new ntuple
 */
#define NEW_NT_SIZE 4096

ntuple h_new(int ndim)
{
     ntuple nt;
     int i;
     
     if ( (nt = (ntuple) malloc(sizeof(ntuple_t))) == NULL)
	  return NULL;
     
     nt->ndim = ndim;
     nt->ndata = 0;
     nt->rev = 0;
     nt->title = NULL;
     nt->label = NULL;
     nt->nhigh = nt->nlow = NULL;
     nt->extremeBad = 0;
     
     /*
      * allocate memory for data.
      */
     if ( (nt->data = (float **)calloc(nt->ndim,sizeof(float *)))
	 == NULL)
	  goto error_ret;
     for (i=0; i<nt->ndim; i++)
     {
	  if ( (nt->data[i] = 
		(float *)malloc(NEW_NT_SIZE*sizeof(float)))
	      == NULL)
	       goto error_ret;
     }	  
     nt->memAlloc = NEW_NT_SIZE;

     /*
      * arrays for minimum/maximum value of data dimension n.
      */
     if ((nt->nlow = (float *) malloc(ndim * sizeof(float))) == NULL)
	  goto error_ret;
     if ((nt->nhigh = (float *) malloc(ndim * sizeof(float))) == NULL) 
	  goto error_ret;
     for (i = 0; i < ndim; i++) {
	  nt->nlow[i] = FLT_MAX;
	  nt->nhigh[i] = -FLT_MAX;
     }

     /*
      * title of ntuple and labels for each dimension.
      */
     if ((nt->label = (char **)malloc(ndim * sizeof(char *))) == NULL)
	  goto error_ret;

     /*
      * set title to blank string; XDR cannot handle NULL pointers as strings.
      */
     if ((nt->title = (char *)malloc( 2*sizeof(char) )) == NULL)
	  goto error_ret;
     strcpy(nt->title, "");
     for (i=0; i<ndim; i++ ) 
     {
	  if ((nt->label[i] = (char *)malloc( 20*sizeof(char) )) == NULL)
	       goto error_ret;
	  sprintf( nt->label[i], "Item %d", i);
     }
          
     return nt;

error_ret:
     h_freeNt( nt );
     return (ntuple) NULL;
}

int h_freeNt( ntuple nt )
{
     int i;
     
     if (nt == NULL) return -1;
     
     /*
      * free memory for data.
      */
     if (nt->data != NULL)
     {
	  for (i=0; i<nt->ndim; i++)
	       if (nt->data[i] != NULL) free( nt->data[i] );
	  free( nt->data );
     }
     
     /*
      * arrays for minimum/maximum value of data dimension n.
      */
     if (nt->nlow != NULL) free( nt->nlow );
     if (nt->nhigh != NULL) free( nt->nhigh );

     /*
      * title of ntuple and labels for each dimension.
      */
     if (nt->title != NULL) free( nt->title );
     if (nt->label != NULL)
     {
	  for (i=0; i<nt->ndim; i++ ) 
	       if (nt->label[i] != NULL) free( nt->label[i] );
	  free( nt->label );
     }
     
     
     free( nt );
     
     return 0;
}

/*
 * Calculate the approximate size to write out an ntuple.
 */
int h_ntSize( ntuple nt )
{
     int i;
     int j;

     if (nt == NULL) return 0;
     
     i = 4;			/* magic number */
     i += (strlen(STRUCT_VERSION)/4 + 2)*4;
     i += sizeof( ntuple_t  )+8;

     i += (strlen(nt->title)/4 + 2)*4;
     for (j=0; j<nt->ndim; j++)
	  i += (strlen(nt->label[j])/4 + 2)*4;

     i += 2 * (nt->ndim * sizeof(float) + 4); /* nlow and nhigh */
     i += nt->ndata*nt->ndim * sizeof(float) + 4;
     
     i += 100;			/* just in case */
     
     return i;
}

int h_fill(ntuple nt,  ...)
{
     va_list argPtr;
     int i;
     float *dat;
     
     if (nt == NULL) return -1;
     
     if ( (dat = (float *)malloc(nt->ndim * sizeof(float))) == NULL)
	  return -1;
     
     va_start(argPtr, nt);
     
     for (i = 0; i < nt->ndim; i++)
	  dat[i] = va_arg(argPtr, double);

     va_end(argPtr);
     
     i = h_arrayFill(nt,dat);
     free(dat);
     
     return i;
}

int h_arrayFill(ntuple nt, float *data )
{
     int i, newSize;
     void *tmp;
     
     if (nt == NULL) return -1;
     
     if (nt->ndata == nt->memAlloc) 
     {
	  newSize = nt->memAlloc * 1.5;
	  for (i=0; i<nt->ndim; i++)
	  {
	       if ((tmp = realloc(nt->data[i], newSize * sizeof(float)))
		   == NULL)
		    return -1;
	       nt->data[i] = (float *)tmp;
	  }
	  nt->memAlloc = newSize;
     }
     
     for (i = 0; i < nt->ndim; i++) {
	  nt->data[i][nt->ndata] = data[i];
	  
	  if (data[i] < nt->nlow[i]) nt->nlow[i] = data[i];
	  if (data[i] > nt->nhigh[i]) nt->nhigh[i] = data[i];
     }
     nt->ndata++;
     
     return 0;
}

int h_setNtTitle( ntuple nt, const char *title )
{
     int l = strlen(title);
     
     /* 
      * allocate space for title 
      */
     if (nt->title != NULL) free( nt->title );
     if ((nt->title = (char *) malloc((l+1) * sizeof(char))) == NULL)
     {
	  return -1;
     }
     
     strcpy(nt->title, title);
     
     return 0;
}

int h_setNtLabel( ntuple nt, int dim, const char *label )
{
     int l = strlen(label);
     
     if (dim >= nt->ndim || dim < 0) return -1;

     /* allocate space for label */
     if (nt->label[dim] != NULL) free( nt->label[dim] );
     if ((nt->label[dim] = (char *) malloc( (l+1) * sizeof(char))) == NULL)
     {
	  return -1;
     }
     
     strcpy(nt->label[dim], label);
     
     return 0;
}

int h_setAllNtLabels( ntuple nt, ... )
{
     va_list argPtr;
     int i, l;
     char *label;
     
     if (nt == NULL) return -1;
     
     va_start(argPtr, nt);
     
     for (i = 0; i < nt->ndim; i++)
     {
	  label = va_arg(argPtr, char *);
	  l = strlen(label);
     
	  /* allocate space for label */
	  if (nt->label[i] != NULL) free( nt->label[i] );
	  if ((nt->label[i] = (char *) malloc( (l+1) * sizeof(char))) == NULL)
	       return -1;
	  
	  strcpy(nt->label[i], label);
     }
     va_end(argPtr);
      
     return 0;
}


int h_clrNt( ntuple nt )
{
     int i;
     void *tmp;
     
     nt->ndata = 0;

     /*
      * allocate memory for data.
      */
     nt->memAlloc = NEW_NT_SIZE;
     for (i=0; i<nt->ndim; i++)
     {
	  if ((tmp = realloc(nt->data[i],NEW_NT_SIZE*sizeof(float)))
	      == NULL)
	       return -1;
	  nt->data[i] = (float *) tmp;
	  
     }	  

     for (i = 0; i < nt->ndim; i++)
     {
	  nt->nlow[i] = FLT_MAX;
	  nt->nhigh[i] = -FLT_MAX;
     }
     nt->rev++;
     
     return 0;
}


const char *h_getNtLabel( ntuple nt, int dim )
{
     if (nt != NULL && dim>=0 && dim < nt->ndim) return nt->label[dim];
     return NULL;
}

float *h_getNtData( ntuple nt, int i_nt, float *f, int *fSize )
{
     int i;
     
     if (nt == NULL) return NULL;
     if (i_nt >= nt->ndata) return NULL;

     /*
      * Check the size of f. If it is too small, make it the right size.
      */
     if (f == NULL || *fSize == 0)
     {
	  if ((f = (float *)malloc(nt->ndim*sizeof(float))) == NULL)
	       return NULL;
	  *fSize = nt->ndim;
     }
     else if (*fSize < nt->ndim)
     {
	  if ((f = (float *)realloc(f,nt->ndim*sizeof(float))) == NULL)
	       return NULL;
	  *fSize = nt->ndim;
     }
     
     for (i=0; i<nt->ndim; i++) f[i] = nt->data[i][i_nt];
     
     return f;
}

int h_replData( ntuple nt, int i_nt, ... )
{
     va_list argPtr;
     int i;
     float *dat;
     
     if (nt == NULL) return -1;
     
     if ( (dat = (float *)malloc(nt->ndim * sizeof(float))) == NULL)
	  return -1;
     
     va_start(argPtr, nt);
     
     for (i = 0; i < nt->ndim; i++)
	  dat[i] = va_arg(argPtr, double);

     va_end(argPtr);
     
     i = h_arrayReplData(nt, i_nt, dat);
     free(dat);
     
     return i;
}

int h_arrayReplData( ntuple nt, int i_nt, float *data )
{
     int i;
     float q;
     
     if (i_nt >= nt->ndata) return -1;

     for (i = 0; i < nt->ndim; i++) 
     {
	  q = nt->data[i][i_nt] = data[i];
	  
	  if (q < nt->nlow[i]) nt->nlow[i] = q;
	  if (q > nt->nhigh[i]) nt->nhigh[i] = q;
     }
     
     nt->rev++;
     if (nt->rev > INT_MAX-100) nt->rev = 0;

     nt->extremeBad = 1;
     
     return 0;
}

int h_findExtreme( ntuple nt )
{
     int i;
     float *p, *last;
     float low, high;
     
     if (nt == NULL) return -1;
     
     for (i=0; i<nt->ndim; i++)
     {
	  low = FLT_MAX;
	  high = -FLT_MAX;
	  last = &nt->data[i][nt->ndata];
	  for (p= nt->data[i]; p<last; p++)
	  {
	       if (*p < low) low = *p;
	       if (*p > high) high = *p;
	  }
	  nt->nlow[i] = low;
	  nt->nhigh[i] = high;
     }

     nt->extremeBad = 0;
     return 0;
}
	  

int h_addColumn( ntuple nt )
{
     void *tmp;
     
     if (nt == NULL) return -1;

     /*
      * add a new column.
      * Use tmp pointer when reallocing to make sure we can get the memory
      *  before committing.
      * Don't increment ndim until end; if we abort, ntuple will be
      *  left in mostly consistent state.
      */

     if ((tmp = realloc(nt->data,(nt->ndim+1)*sizeof(float *)))
	 == NULL)
	  return -1;
     nt->data = (float **)tmp;
     
     nt->data[nt->ndim] = (float *)calloc(nt->memAlloc,sizeof(float));
     if (nt->data[nt->ndim] == NULL) return -1;
     
     /*
      * realloc the low/high arrays
      */
     if ((tmp = realloc(nt->nlow, (nt->ndim+1)*sizeof(float))) == NULL)
	  return -1;
     nt->nlow = (float *)tmp;
     if ((tmp = realloc(nt->nhigh, (nt->ndim+1)*sizeof(float))) == NULL)
	  return -1;
     nt->nhigh = (float *)tmp;
     nt->nlow[nt->ndim] = FLT_MAX;
     nt->nhigh[nt->ndim] = -FLT_MAX;

     /*
      * add a column label
      */
     if ((tmp = realloc(nt->label, (nt->ndim+1)*sizeof(char *))) == NULL)
	  return -1;
     nt->label = (char **)tmp;
     if ((nt->label[nt->ndim] = (char *)malloc( 20*sizeof(char) )) == NULL)
	  return -1;
     sprintf( nt->label[nt->ndim], "Item %d", nt->ndim);

     nt->ndim++;
     nt->extremeBad = 1;
     
     return nt->ndim-1;
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.