/*@qxgϊɂM̊ϑM񕜃vO */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <complex.h>

#define complex complex<float>

void Comparator(float data[], float result[], int size);
void CrossingDetect(float data[], float result[], int size);
void Hilbert(float data[], float result[], int size);
void IntegralandExp(float data[], float result[], int size);
void Multiply(float data1[], float data2[], float result[], int size);
void FileWrite( float data[], int size, char fname[] );

main(int argc, char *argv[])
{
	FILE *fp;
	int i;
	int size;
	float *data;
	float *modulated;
	float *comparator;
	float *zerocross;
	float *hilbert;	
	float *integral;
	float *result;
	static char buff[256];

	fp = fopen( argv[1], "rt" );
	if( fp == NULL )
	{
		printf( "Can't open file\n" );
		exit(0);
	}

	size = atoi( argv[2] );

	data = (float *)malloc( sizeof(float)*size );		/* f[^̊i[̈m */
	comparator = (float *)malloc( sizeof(float)*size );
	zerocross = (float *)malloc( sizeof(float)*size );
	hilbert = (float *)malloc( sizeof(float)*size );
	integral = (float *)malloc( sizeof(float)*size );
	result = (float *)malloc( sizeof(float)*size );

	for( i = 0; i < size; i++ )	/* f[^̓ǂݍ */
	{
		fgets( buff, 256, fp ); 
		data[i] = atof( buff );
	}

	fclose( fp );

	Comparator( data, comparator, size );			/* Rp[^@Ql */
	FileWrite( comparator, size, "comparator.txt" );
	CrossingDetect( comparator, zerocross, size );		/* [o@*/
	FileWrite( zerocross, size, "zerocross.txt" );

	Hilbert( zerocross, hilbert, size );			/* qxgϊ@*/
	FileWrite( hilbert, size, "hilbert.txt" );

	IntegralandExp( hilbert, integral, size );		/* ϕCwϊ */
	FileWrite( integral, size, "integral.txt" );

	Multiply( integral, comparator, result, size );		/* Rp[^o͂Ƃ̊|Z */
		
	for( i = 0; i < size; i++ )
	{
		printf( "%i, %f\n", i, result[i] );		/* ʂ̏o */	}
}

void Comparator( float data[], float result[], int size )@@@	/* Rp[^ */
{
	int i;

	for( i = 0; i < size; i++ )
	{
		if( data[i] >= 0.0 )
			result[i] = 1.0;
		else			result[i] = -1.0;		}	
}

void CrossingDetect( float data[], float result[], int size )	/* [o@*/
{
	int i;
	float current;
	
	current = data[0];	
	for( i = 1; i < size; i++ )
	{
		if( data[i] != current )
		{
			result[i] = 3.141592;
			current = data[i];	
		}
		else
		{
			result[i] = 0.0;
		}
	}
}	
	
void Hilbert( float data[], float result[], int size )		/* qxgϊ@*/
{
	int i, j;
	
	for( i = 0;i < size; i++ )
	{
		result[i] = 0.0;
	}

	for( i = 0; i < size; i++ )
	{
		if( data[i] == 0.0 )
			continue;
		for( j = 0; j < size; j++ )
		{
			if( j == i )
				continue;
			else
				result[j] += data[i]*1.0/(j - i);
		}
	}
}

void IntegralandExp( float data[], float result[], int size )	/* ϕCwϊ */
{
	int i;
	float integral=0.0; 

	for( i = 0; i < size; i++ )
	{
		integral += data[i];
		result[i] = exp(integral);
	}
}

void Multiply( float data1[], float data2[], float result[], int size )		/* |Z */
{
	int i;

	for( i = 0; i < size; i++ )
	{
		result[i] = data1[i] * data2[i];
	}
}


void FileWrite( float data[], int size, char fname[] )		/* f[^̏o͗p֐@eXgp@*/
{
	FILE *fp;
	int i;

	fp = fopen( fname, "wt" );
	if( fp == NULL )
	{
		printf( "File (%s) can't open\n", fname );
		exit(0);
	}
	for( i = 0; i < size; i++ )
	{
		fprintf( fp, "%d, %f\n", i, data[i] );
	}

	fclose(fp);
} 
