DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T g

⟦adb8eea45⟧ TextFile

    Length: 4186 (0x105a)
    Types: TextFile
    Names: »group.c«

Derivation

└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
    └─ ⟦this⟧ »EUUGD11/euug-87hel/sec1/graph/group.c« 

TextFile

/*
 * Copyright (C) 1986   Alan Kent
 *
 * Permission is granted to freely distribute part or
 * all of this code as long as it is not for profit
 * and this message is retained in the code.
 *
 * No resposibility is taken for any damage or incorect
 * results this program generates.
 * 
 */


#include <stdio.h>
#include "graph.h"
#include "y.tab.h"


/*#define DEBUG(parms)	fprintf parms*/
#define DEBUG(parms)


/* This produces a 3 column table: $1 = lower bound of range, $2 = upper */
/* bound of range, $3 = result for range */


extern table_st *new_table ();
extern double ceil ();
extern tnode_st *tab_node ();
extern double call_var_fun ();
extern double min_fun ();
extern double max_fun ();



table_st *
group ( table , range , interval , fun_name )
table_st *table;	/* table of data to group */
range_st *range;	/* contains min,max and interval sizes */
int_st *interval;
char *fun_name;		/* expression to evaluate per interval */
{
    double low , high;
    double value;
    int i , intv , num_intervals , new_index;
    table_st *newtab;
    table_st *temptab;
    int intv_from , intv_to;
    range_st st_range;
    parm_st parm;


    if ( interval == NULL )
	abort ( "code error for group(): NULL interval pointer" );
    if ( num_cols ( table ) != 2 )
	abort ( "GROUP requires two column tables" );

    if ( range == NULL ) {
	range = &st_range;
	st_range.min = min_fun ( table , 0 , table->size );
	st_range.max = max_fun ( table , 0 , table->size );
    }

    if ( interval->int_type == INUMINT ) {
	num_intervals = (int) ceil ( interval->value );
    }
    else {
	num_intervals = 0;
	for ( low = range->min; low <= range->max; low += interval->value )
	    num_intervals++;
    }
    newtab = new_table ( 3 , num_intervals );

DEBUG((stderr,"min %f, max %f, num_int %d\n",range->min,range->max,num_intervals));

    /* now scan through each interval and determine range from table */
    /* that lie within that interval */

    intv_to = 0;
    while ( intv_to < table->size  &&  table->data[intv_to] < range->min )
	intv_to++;
    intv_to--;
    intv = 0;
    new_index = 0;
    low = range->min;
    high = range->min;
    while ( intv < num_intervals ) {
	if ( interval->int_type == INUMINT )
	    high = range->min + ( ((double)intv + 1)
		* ( range->max - range->min ) / (double)num_intervals );
	else
	    high += interval->value;
DEBUG((stderr,"intv %d of %d, low = %f, high = %f\n",intv,num_intervals,low,high));
	for ( i = intv_to + 1; i < table->size; i++ ) {
	    value = table->data[i];
	    if ( value < low )
		abort ( "table must be sorted on group (first) field for GROUP" );
	    /* on last interval, include upper bound */
	    if ( intv + 1 == num_intervals ) {
		if ( value > high )
		    break;
	    }
	    else {
		if ( value >= high )
		    break;
	    }
	}
	intv_from = intv_to + 1;
	intv_to = i - 1;

	/* only do something if the interval contains data */

	if ( intv_to > intv_from ) {

DEBUG((stderr,"intv_to %d > intv_from %d\n",intv_to,intv_from));

	    if ( interval->int_type == INUMINT )
		value = range->min + ( ((double)(intv+1))
		    * ( range->max - range->min ) / (double)num_intervals );
	    else
		value = ((double)(intv+1)) * interval->value;
	    newtab->next->data[ new_index ] = value;

	    if ( interval->int_type == INUMINT )
		value = range->min + ( ((double)intv)
		    * ( range->max - range->min ) / (double)num_intervals );
	    else
		value = ((double)intv) * interval->value;
	    newtab->data[ new_index ] = value;

	    temptab = new_table ( 1 , intv_to - intv_from + 1 );
	    for ( i = 0; i < temptab->size; i++ )
		temptab->data[i] = table->next->data[ i + intv_from ];
	    parm.next = NULL;
	    parm.parm_type = TABLE;
	    parm.tab_expr = tab_node ( TAB_CONST );
	    parm.tab_expr->table = temptab;
	    value = call_var_fun ( fun_name , &parm , NULL , 0 );
	    free_table ( temptab );
DEBUG((stderr,"Function returns %f\n",value));

	    newtab->next->next->data[ new_index ] = value;

	    new_index++;
	}
else
DEBUG((stderr,"intv_from %d <= intv_to %d\n",intv_from,intv_to));
	intv++;
	low = high;
    }
    newtab->size = new_index;
    free_table ( table );
    return ( newtab );
}