/* l`qrvO */
/* b{{ɂċLqifZj@*/

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

	
#define SIZE 1024
#define WINDOW 16 
#define ARORDER 2


extern void DMatPrint( double *a[], int row, int colum );
extern void DMatTrans( double *a[], double *result[], int row, int colum );
extern int DMatInv( double *a[], double *result[], int row, int colum );
extern void DMatAdd( double *a[], double *b[], double *result[], int row,
	int colum );
extern void DMatSub( double *a[], double *b[], double *result[], int row,
	int colum );
extern int DMatMultiply( double *a[], double *b[], double *result[], 
	int row1, int colum1, int row2, int colum2, int row3, int colum3 );
extern int Dka( double *c, complex *result, int n, double eps);


main(int argc, char *argv[] )
{
	FILE *fp;
	static double wave[SIZE];
	static double data[WINDOW+ARORDER*2];

	double *a[ARORDER*2];		
	double *h[WINDOW];		
	double *x[WINDOW];
	double *ht[ARORDER*2];
	double *hth[ARORDER*2];
	double *hthinv[ARORDER*2];
	double *result[ARORDER*2];

	double keisuu[5];
	complex solution[ARORDER*2];
	int i, j, k;
	char buff[256];
	complex freq[ARORDER*2];
	
	double check[20];
	double *test[ARORDER*2];
	double temp;
	complex ctemp;
	
	for( i = 0; i < WINDOW; i++ )	/* z̃m */
	{
		h[i] = (double *)malloc( sizeof(double)*ARORDER*2 );
		x[i] = (double *)malloc( sizeof(double)*1 );
		if( h[i] == NULL || x[i] == NULL )
			printf( "Memory Over\n" );
	}
	for( i = 0; i < ARORDER*2; i++ )
	{
		a[i] = (double *)malloc( sizeof(double)*1 );
		ht[i] = (double *)malloc( sizeof(double)*WINDOW );
		hth[i] = (double *)malloc( sizeof(double)*ARORDER*2 );
		hthinv[i] = (double *)malloc( sizeof(double)*ARORDER*2 );
		result[i] = (double *)malloc( sizeof(double)*WINDOW );
		if( a[i] == NULL || ht[i] == NULL || 
				hth[i] == NULL || hthinv[i] == NULL || result[i] == NULL )
			printf( "Memory Over\n" );

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

	for( i = 0; i < SIZE; i++ )	/* f[^ǂݍ */
	{
		fgets( buff, 256, fp );
		wave[i] = atof( buff );
	}	
	
	for( i = 0; i < SIZE-WINDOW-ARORDER*2; i++ )
	{
		memcpy( data, &wave[i], sizeof(double)*(WINDOW+ARORDER*2));
		for( j = 0; j < WINDOW; j++ )
		{
			x[j][0] = data[WINDOW+ARORDER*2-j-1];
			for( k = 0; k < ARORDER*2; k++ )
			{
				h[j][k] = data[WINDOW+ARORDER*2-j-1-(k+1)];
			}
		}
				
		DMatTrans(h, ht, WINDOW, ARORDER*2);	/* H̓]usvZ */
		DMatMultiply( ht, h, hth, 		/* H^t H ̌vZ */
			ARORDER*2, WINDOW, WINDOW, ARORDER*2, ARORDER*2, ARORDER*2 );
		DMatInv( hth, hthinv, ARORDER*2, ARORDER*2 );	/* H^t H̋tšvZ */
		
		DMatMultiply( hthinv, ht, result, 
			ARORDER*2, ARORDER*2, ARORDER*2, WINDOW, ARORDER*2, WINDOW );  /* (H^t H)^-1 H^t vZ */
		DMatMultiply( result, x, a,
			ARORDER*2, WINDOW, WINDOW, 1, ARORDER*2, 1 );		/* a^ vZ@*/	

		for( j = 0; j < ARORDER*2; j++ )	
		{
			keisuu[j] = -a[ARORDER*2-1-j][0];
		}
		keisuu[ARORDER*2] = 1.0;
		
		Dka( keisuu, solution, ARORDER*2, 1.0e-6 );	/* a^WƂ鑽̉DKA@pĉ */

		for( j = 0; j < ARORDER*2; j++ )	/* ̉g߂ */
		{
			freq[j] = log(solution[j]);
		}

		for( k = 0; k < ARORDER*2; k++ )	/* g̋傫̂ёւ */
		{
			for( j = k; j < ARORDER*2; j++ )
			{
				if( imag(freq[j]) > imag(freq[k]) )
				{
					ctemp = freq[j];
					freq[j] = freq[k];
					freq[k] = ctemp;	
				}
			}
		} 
		
		for( j = 0; j < ARORDER*2-1; j++ )
		{
			printf( "%f, ", imag(freq[j]));
		}
		printf( "%f\n", imag(freq[ARORDER*2-1]) );
	}
}
