ftp.nice.ch/pub/next/science/mathematics/workbench/Histogram.s.tar.gz#/Histogram/DataCounter.m

This is DataCounter.m in view mode; [Download] [Up]

// By Judy D. Halchin, Educational Computing Services, Allegheny College.
// You may freely copy, distribute and reuse this code. 
// Allegheny College and the author disclaim any warranty of any kind, 
// expressed or implied, as to its fitness for any particular use.
// This work was partially supported by a Teacher Preparation grant from the 
// National Science Foundation.

#import "DataCounter.h"

#import <stdlib.h>
#import <stdio.h>
#import <math.h>

@implementation DataCounter

- (float *)countFrequenciesForData:(int *)data
				count:(int)count
				min:(int *)dataMin
				max:(int *)dataMax
				minMaxProvided:(BOOL)minMaxProvided
{
	int datum, numFreq;
	float *frequencies;
	
	//find minimum and maximum data if they weren't provided
	  if (!minMaxProvided)
	  {
	  	*dataMax = data[0];
	  	*dataMin = data[0];
	  	for (datum = 1; datum < count; datum++)
	  	{
	  	  	if (data[datum] > *dataMax)
		  	  	*dataMax = data[datum];
	  	  	if (data[datum] < *dataMin)
		  	  	*dataMin = data[datum];
	 	}
	  }
	  
	//set up the list of frequencies
	  numFreq = *dataMax - *dataMin + 1;
	  frequencies = (float *)malloc(numFreq * sizeof(float));
	  for (datum = 0; datum < numFreq; datum++)
	  	  frequencies[datum] = 0;

	  for (datum = 0; datum < count; datum++)
	  	  frequencies[data[datum]-*dataMin] = 
		  							frequencies[data[datum]-*dataMin] + 1;
	
	return frequencies;
}

- (float *)countFrequenciesForData:(float *)data 
				count:(int)count 
				numGroups:(int)numGroups 
				mins:(float *)mins 
				maxs:(float *)maxs
{
	int group, datum;
	float *frequencies;
	
	frequencies = (float *)malloc(numGroups * sizeof(float));
	for (group = 0; group < numGroups; group++)
	  	frequencies[group] = 0;
	
	for (datum = 0; datum < count; datum++)
	{
		for (group = 0; (data[datum] > maxs[group]) && (group < numGroups);
																 group++);
		if (group < numGroups)
			if (data[datum] >= mins[group])
				frequencies[group] = frequencies[group] + 1;
	}
		
	return frequencies;
}

				
- (float *)countFrequenciesForData:(float *)data 	
				count:(int)count 
				numIntervals:(int)numIntervals 	
				boundaries:(float *)boundaries
{
	int datum, interval;
	float *frequencies;
	
	frequencies = (float *)malloc(numIntervals * sizeof(float));
	
	for (interval = 0; interval < numIntervals; interval++)
		frequencies[interval] = 0;
		
	for (datum = 0; datum < count; datum++)
	{
		for (interval = 0; (data[datum] > boundaries[interval+1]) && 
									(interval < numIntervals); interval++);
		if (interval < numIntervals)
			if (data[datum] > boundaries[interval])
				frequencies[interval] = frequencies[interval] + 1;
	}
		
	return frequencies;
}
			
- findNumIntervals:(int *)numIntervals 
				boundaries:(float **)boundaries 
				forData:(float *)data 
				count:(int)count 
				intervalWidth:(float)intervalWidth
{
	float max, min, powerOfTen=0;
	int numberOfDigits, datum;
	
	//find min and max data values
	  min = data[0];
	  max = data[0];
	  for (datum = 1; datum < count; datum++)
	  	  if (data[datum] < min)
		  	  min = data[datum];
		  else
		  	  if (data[datum] > max)
			  	  max = data[datum];

	//find number of digits of accuracy of the data
	  numberOfDigits = -6;  //we're counting digits right of the decimal
	  
	  for (datum = 0; datum < count; datum++)
	  {
	  	  powerOfTen = pow(10, -numberOfDigits);
	  	  while (fabs(data[datum] - [self round:data[datum] to:powerOfTen])
		  														> 1e-6) 
		  {
		  	  numberOfDigits++;
	  	 	  powerOfTen = pow(10, -numberOfDigits);
		  }  
	  }
	  
	//find bottom boundary
	  *boundaries = (float *)malloc( ((max-min)/intervalWidth+2) * 
	  													sizeof(float));
	  **boundaries = min - 0.5 * powerOfTen; 
	
	//generate groups
	  *numIntervals = 1;
	  while (max > *((*boundaries) + *numIntervals - 1))
	  {
	  	  *((*boundaries) + *numIntervals) = 
		  				*((*boundaries) + (*numIntervals) - 1) + intervalWidth;
		  (*numIntervals)++;
	  }
	  
	  *numIntervals = (*numIntervals) - 1;
	  		
	return self;
}

- (float)round:(float)number to:(float)accuracy
{
	if (number >= 0)
		return (float)(int)(number/accuracy + 0.5) * accuracy;
	else
		return (float)(int)(number/accuracy - 0.5) * accuracy;
}

@end

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