예제 #1
0
파일: sm.cpp 프로젝트: 0branch/qtide
// ---------------------------------------------------------------------
string sm(string c)
{
  rc=0;
  if (c=="act")
    return smact();
  if (c=="active")
    return smactive();
  if (c=="close")
    return smclose();
  if (c=="focus")
    return smfocus();
  if (c=="font")
    return smfont();
  if (c=="get")
    return smget();
  if (c=="html")
    return smhtml();
  if (c=="new")
    return smopen();
  if (c=="open")
    return smopen();
  if (c=="profont")
    return smprofont();
  if (c=="replace")
    return smreplace();
  if (c=="save")
    return smsave();
  if (c=="set")
    return smset();
  else if (c=="prompt")
    return smprompt();
  cmd.getparms();
  return smerror("unrecognized sm command: " + c);
}
예제 #2
0
int main( int argc, char **argv )
{
	/* Counting variables */
	int i,ii,j,jj,k,m,n,p,pp,qq,ret;
	double x,y,x1,x2,rum,sum,tum;

	/* Some generic character buffers and file variables */
	FILE *fp;

	/* Variables for storing ranges */
	long nfr,rng[MAX_NUM_RANGES][2];

	/* Constants needed later */
	const long c_spmat_inc = SPARSE_MAT_INCREMENT;

	/* Point cloud variables */
	int dim,deg,rdn,npts,nbp,mdim,nnb,nrbf,*nb,*drv,*expl,*expr,*ltg,*nlbase,**lbase;
	double *pts,*dlt;
	punity_t pt;
	wfsd_t *rbf;

	/* Quadrature variables */
	double *ctr,*qbox,*nqbox,*qx,qw,rad;
	long *size,*index,*tindex;
	shape_t dm;

	/* Quadrature itself */
	int quadn;
	double *qpts,*qwts;

	/* Sparse matrix variables themselves */
	long *ia,*ja,*ib,*jb,cc;
	double *A,*B,*alpha,*beta,*gamma,*omega,*ev,*eig;
	int mo,neig;

	/* Nuclei variables */
	nuclei_t nuc;

	/* Grid variables for plotting */
	int *dx;
	double *x0,*wx,*dd;

	/* Variables for the not so sparse stuff */
	double *Q;

	/* Variables for configuration */
	int optc;
	symtab_t sym;
	symbol_t *s;

	/* Load file containing variable declarations */
	#include "puksvar.h"

	/* Output who I am */
	fprintf( stderr, "\nPUKSHAM VERSION 0.1\n\n" );

	/* Do all the configuration operations here */
	#include "pukscfg.h"

	/* Allocate all space needed at least initially */
	if( !b_points_loaded )
	{
		fprintf( stderr, " * ERROR: No points loaded. Exiting.\n\n" );
		return 0;
	}
	if( !b_quad_loaded )
	{
		fprintf( stderr, " * ERROR: No quadrature loaded. Exiting.\n\n" );
		return 0;
	}
	if( !b_domain_set )
	{
		fprintf( stderr, " * ERROR: No domain indicator loaded. Exiting.\n\n" );
		return 0;
	}
	if( b_use_external_potential && !b_nuc_loaded )
	{
		fprintf( stderr, " * ERROR: No external potential loaded.\n" );
		fprintf( stderr, " * ERROR: If you want to run without a potential\n" );
		fprintf( stderr, " * ERROR: then set useExternalPotential = no.\n" );
		fprintf( stderr, " * ERROR: Exiting.\n\n" );
		return 0;
	}

	/* Set up the partition of unity */
	dlt = (double*) malloc( npts * sizeof(double) );

	/* Setting up supports */
	fprintf( stderr, " * Generating supports\n\n" );
	generate_cloud_supports_min( dim, npts, pts, rdn, 1.05, dlt, 0.001 );

	/* Initializing Shepard partition of unity */
	fprintf( stderr, " * Initializing Shepard partition of unity " );
	punity_init( &pt, dim, npts, pts, dlt, &cubic_window, &cubic_window_deriv );
#ifdef PUNITY_USE_KDTREES
	generate_cloud_supports_min( dim, npts, pt.pts, rdn, 1.05, pt.dlt, 0.001 );
#endif
	fprintf( stderr, "with rmax = %15.7f\n\n", pt.rmax );

	/* Allocate stuff for integral evaluation */
	ctr = (double*) malloc( dim * sizeof(double) );
        qbox = (double*) malloc( dim * dim * sizeof(double) );
        nqbox = (double*) malloc( dim * dim * sizeof(double) );
        size = (long*) malloc( dim * sizeof(long) );
        index = (long*) malloc( dim * sizeof(long) );
	tindex = (long*) malloc( dim * sizeof(long) );
        qx = (double*) malloc( dim * sizeof(double) );
	expl = (int*) malloc( dim * sizeof(int) );
	expr = (int*) malloc( dim * sizeof(int) );

	/* Allocate space for Laplace operator */
	drv = (int*) malloc( dim * sizeof(int) );

	/* Deal with boundary functions */
	nbp = 0;
	for(i=0;i<npts;i++)
	{
		boundary_indicator( pt.pts + i * dim, &dm, f_bndry_tol, &ret );
		if( ret == 1 )
			++nbp, pt.bdry[i] = 1; /* Set this node to have a singularity to give delta property on boundary */
	}
	fprintf( stderr, " * Detected %d boundary points using given criteria\n\n", nbp );

	  ///////////////////////////////////////////////////////////////////
	 // THIS BLOCK SHOULD BE SOMEHOW TAKEN AS INPUT FROM THE CFG FILE //
	///////////////////////////////////////////////////////////////////

	/* Set up extra basis functions */
	rbf = (wfsd_t*) malloc( 1 * sizeof(wfsd_t) );
	rbf[0] = &exp_func;
	nrbf = 1;

	/* Set up basis on each center; this info should be given as input */
	nlbase = (int*) malloc( npts * sizeof(int) );
	lbase = (int**) malloc( npts * sizeof(int*) );
	for(i=0;i<npts;i++)
	{
		nlbase[i] = 6;
		lbase[i] = (int*) malloc( 16 * sizeof(int) );
		lbase[i][0] = 0;
		lbase[i][1] = 1;
		lbase[i][2] = 2;
		lbase[i][3] = 3;
		lbase[i][4] = 4;
		lbase[i][5] = 5;
		lbase[i][6] = 6;
		lbase[i][7] = 7;
		lbase[i][8] = 8;
		lbase[i][9] = 9;
	}
	nlbase[24] = 7;
	lbase[24][6] = -1;

	/* Adjust nucleus diameter */
	//pt.dlt[12] *= 1.2;

	/* Calculate the dimension of the matrices A and B */
	mdim = 0;
	for(i=0;i<npts;i++)
		if( pt.bdry[i] == 0 )
			mdim += nlbase[i];

	/* Display matrix dimension */
	fprintf( stderr, " * Set matrix dimension to %d\n\n", mdim );

	/* Now that boundary points are known, make final adjustments to Lanczos parameters */
	if( i_max_lanczos_steps > mdim )
	{
		i_max_lanczos_steps = mdim;
		fprintf( stderr, " * ERROR: Value of maxLanczosSteps > mdim: Setting maxLanczosSteps to %d\n\n", mdim );
	}
	if( neig > i_max_lanczos_steps )
	{
		neig = i_max_lanczos_steps;
		fprintf( stderr, " * ERROR: Requested numberEigenvalues > maxLanczosSteps: Setting neig = %d\n\n", i_max_lanczos_steps );
	}

	/* Allocate space for the sparse matrices */
	ia = (long*) malloc( ( mdim + 2 ) * sizeof(long) );
	ib = (long*) malloc( ( mdim + 2 ) * sizeof(long) );
	ja = (long*) malloc( c_spmat_inc * sizeof(long) );
	jb = (long*) malloc( c_spmat_inc * sizeof(long) );
	A = (double*) malloc( c_spmat_inc * sizeof(double) );
	B = (double*) malloc( c_spmat_inc * sizeof(double) );
	cc = c_spmat_inc;

	/* Generate Q for saving Lanczos vectors later */
	Q = (double*) malloc( ( i_max_lanczos_steps + 2 ) * mdim * sizeof(double) );

	/* Loading matrices */
	if( b_load_overl_mat )
	{
		fprintf( stderr, " * Loaded overlap matrix from \"%s\"\n\n", s_overl_fname );
	}
	if( b_load_stiff_mat )
	{
		fprintf( stderr, " * Loaded stiffness matrix from \"%s\"\n\n", s_stiff_fname );
	}

	/* Allocate the index space for excluding boundary points */
	ltg = (int*) malloc( ( npts - nbp ) * sizeof(int) );

	/* Build list of non-boundary particles */
	for(i=0,p=0;i<npts;i++)
		if( pt.bdry[i] == 0 )
			ltg[p++] = i;

	/* Call matrix build function */
	fprintf( stderr, " * Building system matrices " );
	puksham_mbuild( &pt, mdim, nbp, &dm, nlbase, lbase, rbf, ltg, &nuc, quadn, qpts, qwts, &ia, &ja, &A, &ib, &jb, &B, cc, c_spmat_inc,
				b_use_external_potential, b_load_overl_mat, b_load_stiff_mat, b_use_singular, i_sing_order,
					&b_have_stiff_mat, &b_have_overl_mat );

	/* Don't go on if the matrices have not been loaded or built */
	if( !b_have_stiff_mat )
	{
		fprintf( stderr, " * ERROR: Stiffness matrix has not been built. This is really bad. Exiting angrily.\n\n" );
		return 0;
	}
	if( !b_have_overl_mat )
	{
		fprintf( stderr, " * ERROR: Overlap matrix has not been built. This is really bad. Exiting angrily.\n\n" );
		return 0;
	}

	/* Saving matrices to output files */
	if( b_save_stiff_mat || b_save_overl_mat )
		fprintf( stderr, " * Writing matrix output files\n\n" );
	if( b_save_overl_mat )
        {
		smsave( s_overl_fname, mdim, mdim, ib, jb, B, 1 );
                fprintf( stderr, " ---> Saved overlap matrix to output \"%s\"\n", s_overl_fname );
        }
	if( b_save_stiff_mat )
	{
		smsave( s_stiff_fname, mdim, mdim, ia, ja, A, 1 );
		fprintf( stderr, " ---> Saved stiffness matrix to output \"%s\"\n", s_stiff_fname );
	}
	if( b_save_overl_mat || b_save_stiff_mat )
		fprintf( stderr, "\n" );

	/* Solve the eigenvalue problem via Lanczos projection */
	if( !b_neig_set || ( b_neig_set && neig > mdim ) )
	{
		fprintf( stderr, " * ERROR: Number of eigenvalues not specified or invalid. Exiting.\n\n " );
		return 0;
	}
	alpha = (double*) malloc( ( i_max_lanczos_steps + 2 ) * sizeof(double) );
	beta = (double*) malloc( ( i_max_lanczos_steps + 2 ) * sizeof(double) );
	gamma = (double*) malloc( ( i_max_lanczos_steps + 2 ) * sizeof(double) );
	omega = (double*) malloc( ( i_max_lanczos_steps + 2 ) * sizeof(double) );
	ev = (double*) malloc( 2 * ( i_max_lanczos_steps + 2 ) * sizeof(double) );
	eig = (double*) malloc( ( neig + 2 ) * mdim * sizeof(double) );

	/* Seed the random number generator */
	srand((unsigned)time(0));

	/* Lanczos procedure */
	fprintf( stderr, " * Beginning Lanczos procedure\n\n" );
	sgsilanczoscr( mdim, i_max_lanczos_steps, neig, ib, jb, B, ia, ja, A, alpha, beta, omega, NULL, ev, Q, &mo, 1e-16, &x, 10000, 0, &ret );
	fprintf( stderr, " * Converged Lanczos procedure in %d steps with a collective residual of %5.9e over all EV's\n\n", mo, x );

	/* Now for sgsilanczos need to prepare alpha, beta by premultiplying by inverse of diag(omega) */
	copy( mo + 2, beta, gamma );
	for(i=0;i<mo-1;i++)
		alpha[i] /= omega[i], beta[i+1] /= omega[i], gamma[i+1] /= omega[i+1];
	alpha[mo-1] /= omega[mo-1];

	/* Solve the appropriate tridiagonal eigenvalue problem */
	if( strncmp( s_treig_routine, "lr", TOKEN_BUFFER_LENGTH ) == 0 )
		treiglr( mo, alpha, beta + 1, gamma + 1, 10000, ev, &ret, &n );
	else if( strncmp( s_treig_routine, "qds", TOKEN_BUFFER_LENGTH ) == 0 )
		treigqds( mo, alpha, beta + 1, gamma + 1, 10000, ev, &ret, &n );
	else if( strncmp( s_treig_routine, "dqds", TOKEN_BUFFER_LENGTH ) == 0 )
		treigdqds( mo, alpha, beta + 1, gamma + 1, 10000, ev, &ret, &n );
	else if( strncmp( s_treig_routine, "tridqds", TOKEN_BUFFER_LENGTH ) == 0 )
		treigtridqds( mo, alpha, beta + 1, gamma + 1, 10000, ev, &ret, &n );
	else
	{
		fprintf( stderr, " * ERROR: No valid tridiagonal eigenvalue solver selected: Given is \"%s\". Exiting.\n\n", s_treig_routine );
		return 0;
	}
	inverse_complex_bubble_sort( mo, ev );
	fprintf( stderr, " * Eigenvalues resulting from Lanczos process:\n\n" );
	for(i=0;i<neig;i++)
		fprintf( stderr, "%15.7f + %15.7fi\n", 1.0 / ev[2*i+0], ev[2*i+1] );
	fprintf( stderr, "\n" );

	/* Generate the eigenvectors */
	fprintf( stderr, " * Generating eigenvectors\n\n" );

	/* IMPORTANT: The shift mu used here should be an eigenvalue of the original system, not its inverse */
	fprintf( stderr, " ---> Vectors:\n" );
	for(i=0;i<neig;i++)
	{
		nrandv( mdim, eig + i * mdim );
		sgsinvi( mdim, ia, ja, A, ib, jb, B, eig + i * mdim, 1.0 / ev[2*i+0], 1e-9, 20000, 0 );
		fprintf( stderr, " ----> %5d EV = %15.7f: ", i, 1.0 / ev[2*i+0] );
		for(j=0;j<NUM_EIG_DIMS_TO_PRINT;j++)
			fprintf( stderr, "%15.7f", eig[i*mdim+j] );
		fprintf( stderr, "  ...\n" );
	}
	fprintf( stderr, "\n" );

	  /////////////////////////////////
	 // Normalize the wavefunctions //
	/////////////////////////////////

	//fprintf( stderr, " * Normalizing output wave functions\n\n" );
	//for(i=0;i<dim;i++)
	//	for(j=0;j<dim;j++)
	//		if( j == i )
	//			nqbox[i*dim+j] = 1.0;
	//		else
	//			nqbox[i*dim+j] = 0.0;
	//for(i=0;i<neig;i++)
	//{
	//	sum = 0.0;
	//	for(j=0;j<npts;j++)
	//	{
	//		for(k=0;k<dim;k++)
	//			index[k] = 0, size[k] = (long) quadn - 1;
	//		do
	//		{
	//			/* Calculate the spherical gauss point for this index */
	//			copy( dim, pt.pts + j * dim, ctr );
	//			rad = pt.dlt[j];
	//			sphere_gauss_point( dim, ctr, rad, nqbox, index, qpts, qwts, qx, &qw );
	//			domain_indicator( qx, &dm, &ret );
	//			if( ret == 1 )
	//				sum += qw * punity_evaluate( &pt, j, qx );
	//		}
	//		while( arraynext( (long) dim, size, index ) != -1 );
	//	}
	//}

	/* Do some plotting */
	if( b_out_eig_range_set )
	{
		/* Announce */
		fprintf( stderr, " * Plotting eigenvectors " );
		for(i=0;i<nfr;i++)
		{
			if( rng[i][0] == rng[i][1] )
				fprintf( stderr, "%d ", rng[i][0] );
			else if( rng[i][1] > rng[i][0] )
				fprintf( stderr, "%d-%d ", rng[i][0], rng[i][1] );
		}
		fprintf( stderr, "\n\n" );

		for(i=0;i<dim;i++)
			size[i] = (long) dx[i] - 1;
		for(i=0;i<dim;i++)
			index[i] = 0;
		do
		{
			/* Build the point at which to evaluate the eigenfunction */
			for(i=0;i<dim;i++)
				qx[i] = x0[i] + (double) index[i] * dd[i];
	
			/* Output the point for this line */
			for(i=0;i<dim;i++)
				fprintf( stdout, "%15.7f", qx[i] );
	
			/* Now evaluate the function at that point */
			for(n=0;n<nfr;n++)
			{
				for(m=rng[n][0];m<=rng[n][1];m++)
				{
					sum = 0.0;
					for(i=0,pp=0;i<npts-nbp;i++)
					{
						for(ii=0;ii<nlbase[ltg[i]];ii++)
						{
							y = 0.0;
							for(j=0;j<dim;j++)
								y += pow( qx[j] - pt.pts[ltg[i]*dim+j], 2.0 );
							y = sqrt( y );
							if( y < pt.dlt[ltg[i]] )
							{
								if( lbase[ltg[i]][ii] >= 0 )
								{
									global_polynomial_vector( lbase[ltg[i]][ii], dim, expl );
									if( b_use_singular )
										sum += eig[m*mdim+pp] * punity_eval_local_poly_delta( &pt, ltg[i], expl, qx, i_sing_order );
									else
										sum += eig[m*mdim+pp] * punity_eval_local_poly( &pt, ltg[i], expl, qx );
								}
								else
								{
									/* Deal with plotting of localized extra RBFs */
									for(j=0;j<dim;j++)
										ctr[j] = qx[j] - pt.pts[ltg[i]*dim+j];
									sum  += eig[m*mdim+pp] * rbf[-1-lbase[ltg[i]][ii]]( dim, 0, pt.dlt[ltg[i]], ctr ) * punity_evaluate( &pt, ltg[i], qx );
								}
							}
							pp++;
						}
					}

					/* Ouptut the values consecutively */
					fprintf( stdout, "%18.10f", sum );
				}
			}

			/* Close the line */
			fprintf( stdout, "\n" );

			/* Check to see if another newline is needed to maintain gnuplot's preferred format */
			for(i=0;i<dim;i++)
				tindex[i] = index[i];
			arraynext( (long) dim, size, tindex );
			for(i=0;i<dim;i++)
			{
				if( index[i] == dx[i] - 1 && tindex[i] != dx[i] - 1 )
				{
					fprintf( stdout, "\n" );
					break;
				}
			}
		}
		while( arraynext( (long) dim, size, index ) != -1 );
	}

	/* Announce exit */
	fprintf( stderr, " * Exiting happily. Have a nice day!\n\n" );

	/* Don't forget to clean up */
	free( pts ); free( dlt ); free( drv );
	free( qpts ); free( qwts );
	free( ia ); free( ib );
	free( ja ); free( jb );
	free( A ); free( B ); free( Q );
	free( alpha ); free( beta ); free( gamma ); free( omega );
	free( ctr ); free( qbox ); free( nqbox ); free( qx );
	free( size ); free( index );
	free( ev ); free( eig );
	free( ltg ); free( expl ); free( expr );
	for(i=0;i<npts;i++)
		free( lbase[i] );
	free( lbase );
	free( nlbase );
	punity_free( &pt );
	if( b_use_external_potential )
		nuclei_free( &nuc );

	return 0;
}
예제 #3
0
int main( int argc, char **argv )
{
	/* Counting variables */
	int i,j,k,m,n,p,ret;
	double x,y,sum,tum;

	/* Some generic character buffers and file variables */
	FILE *fp;

	/* Variables for storing ranges */
	long nfr,rng[MAX_NUM_RANGES][2];

	/* Constants needed later */
	const long c_spmat_inc = SPARSE_MAT_INCREMENT;

	/* Point cloud variables */
	int dim,deg,rdn,npts,nbp;
	double *pts,*dlt;
	int *drv;
	punity_t pt;

	/* Quadrature variables */
	double *ctr,*qbox,*nqbox,*qx,qw,rad;
	long *size,*index,*tindex;
	int *ltg;
	shape_t dm;

	/* Quadrature itself */
	int quadn;
	double *qpts,*qwts;

	/* Sparse matrix variables themselves */
	long *ia,*ja,*ib,*jb,cc;
	double *A,*B,*alpha,*beta,*gamma,*omega,*ev,*eig;
	int mo,neig;

	/* Nuclei variables */
	nuclei_t nuc;

	/* Grid variables for plotting */
	int *dx;
	double *x0,*wx,*dd;

	/* Variables for the not so sparse stuff */
	double *Q;

	/* Variables for configuration */
	int optc;
	symtab_t sym;
	symbol_t *s;

	/* Load file containing variable declarations */
	#include "puksvar.h"

	/* Output who I am */
	fprintf( stderr, "\nPUKSHAM VERSION 0.1\n\n" );

	/* Do all the configuration operations here */
	#include "pukscfg.h"

	  //////////////////////////////////////////
         // Begin actual code here. Good luck... //
        //////////////////////////////////////////

	/* Allocate all space needed at least initially */
	if( !b_points_loaded )
	{
		fprintf( stderr, " * ERROR: No points loaded. Exiting.\n\n" );
		return 0;
	}
	if( !b_quad_loaded )
	{
		fprintf( stderr, " * ERROR: No quadrature loaded. Exiting.\n\n" );
		return 0;
	}
	if( !b_domain_set )
	{
		fprintf( stderr, " * ERROR: No domain indicator loaded. Exiting.\n\n" );
		return 0;
	}

	/* Check for discrepancies in Lanczos parameters */
	if( i_max_lanczos_steps > npts )
	{
		i_max_lanczos_steps = npts;
		fprintf( stderr, " ---> ERROR: Value of maxLanczosSteps > npts: Setting maxLanczosSteps to %d\n", npts );
	}

	/* Set up the partition of unity */
	dlt = (double*) malloc( npts * sizeof(double) );

	/* Setting up supports */
	fprintf( stderr, " * Generating supports\n\n" );
	generate_cloud_supports_min( dim, npts, pts, rdn, 1.05, dlt, 0.001 );

	/* Initializing Shepard partition of unity */
	fprintf( stderr, " * Initializing Shepard partition of unity " );
	punity_init( &pt, dim, npts, pts, dlt, &cubic_window, &cubic_window_deriv );
#ifdef PUNITY_USE_KDTREES
	generate_cloud_supports_min( dim, npts, pt.pts, rdn, 1.05, pt.dlt, 0.001 );
#endif
	fprintf( stderr, "with rmax = %15.7f\n\n", pt.rmax );

	/* Allocate stuff for integral evaluation */
	ctr = (double*) malloc( dim * sizeof(double) );
        qbox = (double*) malloc( dim * dim * sizeof(double) );
        nqbox = (double*) malloc( dim * dim * sizeof(double) );
        size = (long*) malloc( dim * sizeof(long) );
        index = (long*) malloc( dim * sizeof(long) );
	tindex = (long*) malloc( dim * sizeof(long) );
        qx = (double*) malloc( dim * sizeof(double) );

	/* Allocate space for the sparse matrices */
	ia = (long*) malloc( npts * sizeof(long) );
	ib = (long*) malloc( npts * sizeof(long) );
	ja = (long*) malloc( c_spmat_inc * sizeof(long) );
	jb = (long*) malloc( c_spmat_inc * sizeof(long) );
	A = (double*) malloc( c_spmat_inc * sizeof(double) );
	B = (double*) malloc( c_spmat_inc * sizeof(double) );
	cc = c_spmat_inc;

	/* Allocate space for Laplace operator */
	drv = (int*) malloc( dim * sizeof(int) );

	/* Deal with boundary functions */
	nbp = 0;
	for(i=0;i<npts;i++)
	{
		boundary_indicator( pt.pts + i * dim, &dm, f_bndry_tol, &ret );
		if( ret == 1 )
			++nbp, pt.bdry[i] = 1; /* Set this node to have a singularity to give delta property on boundary */
	}
	fprintf( stderr, " * Detected %d boundary points using given criteria\n\n", nbp );

	/* Now that boundary points are known, make final adjustments to Lanczos parameters */
	if( i_max_lanczos_steps > npts - nbp )
	{
		if( i_max_lanczos_steps > npts - nbp )
		{
			i_max_lanczos_steps = npts - nbp;
			fprintf( stderr, " * ERROR: Value of maxLanczosSteps > npts - nbp: Setting maxLanczosSteps to %d\n\n", npts - nbp );
		}
	}
	if( neig > i_max_lanczos_steps )
	{
		neig = i_max_lanczos_steps;
		fprintf( stderr, " * ERROR: Requested numberEigenvalues > maxLanczosSteps: Setting neig = %d\n\n", i_max_lanczos_steps );
	}

	/* Generate Q for saving Lanczos vectors later */
	Q = (double*) malloc( i_max_lanczos_steps * npts * sizeof(double) );

	/* Loading matrices */
	if( b_load_overl_mat )
	{
		fprintf( stderr, " * Loaded overlap matrix from \"%s\"\n\n", s_overl_fname );
	}
	if( b_load_stiff_mat )
	{
		fprintf( stderr, " * Loaded stiffness matrix from \"%s\"\n\n", s_stiff_fname );
	}

	/* Start building the matrices */
	if( !b_load_stiff_mat || !b_load_overl_mat )
	{
		fprintf( stderr, " * Building matrices " );
		/* Otherwise need to build system which does not contain the boundary nodes */
		ltg = (int*) malloc( ( npts - nbp ) * sizeof(int) );
		for(i=0,p=0;i<npts;i++)
			if( pt.bdry[i] == 0 )
				ltg[p++] = i;

		/* Initialize the matrices */
		for(i=0;i<pt.npts-nbp;i++)
			ia[i] = -1, ib[i] = -1;
		p = 0;
		for(i=0;i<npts-nbp;i++)
		{
			for(j=0;j<i/(npts/20);j++)
				fprintf( stderr, "=" );
			fprintf( stderr, ">%3d%%", i * 100 / ( npts - nbp ) );
			for(j=i;j<npts-nbp;j++)
			{
				if( sphere_intersection( dim, pt.pts + ltg[i] * dim, pt.dlt[ltg[i]], pt.pts + ltg[j] * dim, pt.dlt[ltg[j]], ctr, &rad, qbox ) == 1 )
				{
					/* Build the local basis for the intersection of spheres */
					for(k=0;k<dim;k++)
					{
						sum = 0.0;
						for(m=0;m<dim;m++)
							sum += qbox[k*dim+m] * qbox[k*dim+m];
						sum = sqrt( sum );
						for(m=0;m<dim;m++)
							nqbox[k*dim+m] = qbox[k*dim+m] / sum;
					}

					/* Calculate the entries of the inner product matrix */
					for(k=0;k<dim;k++)
						index[k] = 0, size[k] = quadn - 1;
					sum = 0.0, tum = 0.0;
					do
                                	{
                                        	lens_gauss_point( dim, pt.pts + ltg[i] * dim, pt.dlt[ltg[i]], pt.pts + ltg[j] * dim, pt.dlt[ltg[j]],
                                                	rad, nqbox, index, qpts, qwts, qx, &qw );
						domain_indicator( qx, &dm, &ret );
						if( ret == 1 )
						{
							if( !b_load_overl_mat )
							{
                        	                		x = punity_evaluate_delta( &pt, ltg[i], qx, i_sing_order )
										* punity_evaluate_delta( &pt, ltg[j], qx, i_sing_order );
								sum += qw * x;
							}
							if( !b_load_stiff_mat )
							{
								y = 0.0;
								for(k=0;k<dim;k++)
								{
									for(m=0;m<dim;m++)
									{
										if( m == k )
											drv[m] = 1;
										else
											drv[m] = 0;
									}
									y += punity_term_deriv_evaluate_delta( &pt, ltg[i], drv,
													qx, i_sing_order, NULL, 0 )
									* punity_term_deriv_evaluate_delta( &pt, ltg[j], drv,
													qx, i_sing_order, NULL, 0 );
								}
								tum += qw * y;
							}
						}
					}
                                	while( arraynext( (long) dim, size, index ) != -1 );

					/* Now put sum in the i,j entry in the sparse matrx of inner product entries */
					if( p > cc )
					{
						cc += c_spmat_inc;
						if( !b_load_stiff_mat )
						{
							A = (double*) realloc( A, cc * sizeof(double) );
							ja = (long*) realloc( ja, cc * sizeof(long) );
						}
						if( !b_load_overl_mat )
						{
							B = (double*) realloc( B, cc * sizeof(double) );
							jb = (long*) realloc( jb, cc * sizeof(long) );
						}
					}
					if( !b_load_stiff_mat )
					{
						A[p] = tum;
						ja[p] = j;
						if( ia[i] == -1 )
                                                	ia[i] = p;
					}
					if( !b_load_overl_mat )
					{
						B[p] = sum;
						jb[p] = j;
						if( ib[i] == -1 )
                                                	ib[i] = p;
					}

					/* Step to the next entry */
					p++;
				}
			}
			parse_print_back( stderr, i / ( npts / 20 ) + 1 + 4 );
		}
			
		if( !b_load_stiff_mat )
			ia[npts-nbp] = p;
		if( !b_load_overl_mat )
			ib[npts-nbp] = p;
		fprintf( stderr, "\n\n" );

		/* Indicate that matrices are both built */
		if( !b_load_stiff_mat )
			b_have_stiff_mat = 1;
		if( !b_load_overl_mat )
			b_have_overl_mat = 1;
	}

	/* Don't go on if the matrices have not been loaded or built */
	if( !b_have_stiff_mat )
	{
		fprintf( stderr, " * ERROR: Stiffness matrix has not been built. This is really bad. Exiting angrily.\n\n" );
		return 0;
	}
	if( !b_have_overl_mat )
	{
		fprintf( stderr, " * ERROR: Overlap matrix has not been built. This is really bad. Exiting angrily.\n\n" );
		return 0;
	}

	/* Saving matrices to output files */
	if( b_save_stiff_mat || b_save_overl_mat )
		fprintf( stderr, " * Writing matrix output files\n\n" );
	if( b_save_overl_mat )
        {
		smsave( s_overl_fname, npts - nbp, npts - nbp, ib, jb, B, 1 );
                fprintf( stderr, " ---> Saved overlap matrix to output \"%s\"\n", s_overl_fname );
        }
	if( b_save_stiff_mat )
	{
		smsave( s_stiff_fname, npts - nbp, npts - nbp, ia, ja, A, 1 );
		fprintf( stderr, " ---> Saved stiffness matrix to output \"%s\"\n", s_stiff_fname );
	}
	if( b_save_overl_mat || b_save_stiff_mat )
		fprintf( stderr, "\n" );

	/* Solve the eigenvalue problem via Lanczos projection */
	if( !b_neig_set || ( b_neig_set && neig > npts ) )
	{
		fprintf( stderr, " * ERROR: Number of eigenvalues not specified or invalid. Exiting.\n\n " );
		return 0;
	}
	alpha = (double*) malloc( ( npts + 2 ) * sizeof(double) );
	beta = (double*) malloc( ( npts + 2 ) * sizeof(double) );
	gamma = (double*) malloc( ( npts + 2 ) * sizeof(double) );
	omega = (double*) malloc( ( npts + 2 ) * sizeof(double) );
	ev = (double*) malloc( 2 * npts * sizeof(double) );
	eig = (double*) malloc( neig * ( npts - nbp ) * sizeof(double) );

	/* Seed the random number generator */
	srand((unsigned)time(0));

	/* Lanczos procedure */
	fprintf( stderr, " * Beginning Lanczos procedure\n\n" );
	sgsilanczoscr( npts - nbp, i_max_lanczos_steps, neig, ib, jb, B, ia, ja, A, alpha, beta, omega, NULL, ev, Q, &mo, 1e-15, &x, 10000, 0, &ret );
	fprintf( stderr, " * Converged Lanczos procedure in %d steps with a collective residual of %5.9e over all EV's\n\n", mo, x );

	/* Now for sgsilanczos need to prepare alpha, beta by premultiplying by inverse of diag(omega) */
	copy( mo + 2, beta, gamma );
	for(i=0;i<mo-1;i++)
		alpha[i] /= omega[i], beta[i+1] /= omega[i], gamma[i+1] /= omega[i+1];
	alpha[mo-1] /= omega[mo-1];

	/* Solve the appropriate tridiagonal eigenvalue problem */
	if( strncmp( s_treig_routine, "lr", TOKEN_BUFFER_LENGTH ) == 0 )
		treiglr( mo, alpha, beta + 1, gamma + 1, 10000, ev, &ret, &n );
	else if( strncmp( s_treig_routine, "qds", TOKEN_BUFFER_LENGTH ) == 0 )
		treigqds( mo, alpha, beta + 1, gamma + 1, 10000, ev, &ret, &n );
	else if( strncmp( s_treig_routine, "dqds", TOKEN_BUFFER_LENGTH ) == 0 )
		treigdqds( mo, alpha, beta + 1, gamma + 1, 10000, ev, &ret, &n );
	else if( strncmp( s_treig_routine, "tridqds", TOKEN_BUFFER_LENGTH ) == 0 )
		treigtridqds( mo, alpha, beta + 1, gamma + 1, 10000, ev, &ret, &n );
	else
	{
		fprintf( stderr, " * ERROR: No valid tridiagonal eigenvalue solver selected: Given is \"%s\". Exiting.\n\n", s_treig_routine );
		return 0;
	}
	complex_bubble_sort( mo, ev );
	fprintf( stderr, " * Eigenvalues resulting from Lanczos process:\n\n" );
	for(i=0;i<neig;i++)
		fprintf( stderr, "%15.7f + %15.7fi\n", 1.0 / ev[2*i+0], ev[2*i+1] );
	fprintf( stderr, "\n" );

	/* Generate the eigenvectors */
	fprintf( stderr, " * Generating eigenvectors\n\n" );

	/* IMPORTANT: The shift mu used here should be an eigenvalue of the original system, not its inverse */
	fprintf( stderr, " ---> Vectors:\n" );
	for(i=0;i<neig;i++)
	{
		nrandv( npts - nbp, eig + i * ( npts - nbp ) );
		sgsinvi( npts - nbp, ia, ja, A, ib, jb, B, eig + i * ( npts - nbp ), 1.0 / ev[2*i+0], 1e-9, 10000, 0 );
		fprintf( stderr, " ----> %5d EV = %15.7f: ", i, 1.0 / ev[2*i+0] );
		for(j=0;j<NUM_EIG_DIMS_TO_PRINT;j++)
			fprintf( stderr, "%15.7f", eig[i*(npts-nbp)+j] );
		fprintf( stderr, "  ...\n" );
	}
	fprintf( stderr, "\n" );

	  /////////////////////////////////
	 // Normalize the wavefunctions //
	/////////////////////////////////

	//fprintf( stderr, " * Normalizing output wave functions\n\n" );
	//for(i=0;i<dim;i++)
	//	for(j=0;j<dim;j++)
	//		if( j == i )
	//			nqbox[i*dim+j] = 1.0;
	//		else
	//			nqbox[i*dim+j] = 0.0;
	//for(i=0;i<neig;i++)
	//{
	//	sum = 0.0;
	//	for(j=0;j<npts;j++)
	//	{
	//		for(k=0;k<dim;k++)
	//			index[k] = 0, size[k] = (long) quadn - 1;
	//		do
	//		{
	//			/* Calculate the spherical gauss point for this index */
	//			copy( dim, pt.pts + j * dim, ctr );
	//			rad = pt.dlt[j];
	//			sphere_gauss_point( dim, ctr, rad, nqbox, index, qpts, qwts, qx, &qw );
	//			domain_indicator( qx, &dm, &ret );
	//			if( ret == 1 )
	//				sum += qw * punity_evaluate( &pt, j, qx );
	//		}
	//		while( arraynext( (long) dim, size, index ) != -1 );
	//	}
	//}

	/* Do some plotting */
	if( b_out_eig_range_set )
	{
		/* Announce */
		fprintf( stderr, " * Plotting eigenvectors " );
		for(i=0;i<nfr;i++)
		{
			if( rng[i][0] == rng[i][1] )
				fprintf( stderr, "%d ", rng[i][0] );
			else if( rng[i][1] > rng[i][0] )
				fprintf( stderr, "%d-%d ", rng[i][0], rng[i][1] );
		}
		fprintf( stderr, "\n\n" );

		for(i=0;i<dim;i++)
			size[i] = (long) dx[i] - 1;
		for(i=0;i<dim;i++)
			index[i] = 0;
		do
		{
			/* Build the point at which to evaluate the eigenfunction */
			for(i=0;i<dim;i++)
				qx[i] = x0[i] + (double) index[i] * dd[i];
	
			/* Output the point for this line */
			for(i=0;i<dim;i++)
				fprintf( stdout, "%15.7f", qx[i] );
	
			/* Now evaluate the function at that point */
			for(n=0;n<nfr;n++)
			{
				for(m=rng[n][0];m<=rng[n][1];m++)
				{
					sum = 0.0;
					for(i=0;i<npts-nbp;i++)
					{
						y = 0.0;
						for(j=0;j<dim;j++)
							y += pow( qx[j] - pt.pts[ltg[i]*dim+j], 2.0 );
						y = sqrt( y );
						if( y < pt.dlt[ltg[i]] )
							sum += eig[m*(npts-nbp)+i] * punity_evaluate_delta( &pt, ltg[i], qx, i_sing_order );
					}

					/* Ouptut the values consecutively */
					fprintf( stdout, "%15.7f", sum );
				}
			}

			/* Close the line */
			fprintf( stdout, "\n" );

			/* Check to see if another newline is needed to maintain gnuplot's preferred format */
			for(i=0;i<dim;i++)
				tindex[i] = index[i];
			arraynext( (long) dim, size, tindex );
			for(i=0;i<dim;i++)
			{
				if( index[i] == dx[i] - 1 && tindex[i] != dx[i] - 1 )
				{
					fprintf( stdout, "\n" );
					break;
				}
			}
		}
		while( arraynext( (long) dim, size, index ) != -1 );
	}

	/* Announce exit */
	fprintf( stderr, " * Exiting happily. Have a nice day!\n\n" );

	/* Don't forget to clean up */
	free( pts ); free( dlt ); free( drv );
	free( qpts ); free( qwts );
	free( ia ); free( ib );
	free( ja ); free( jb );
	free( A ); free( B ); free( Q );
	free( alpha ); free( beta ); free( gamma ); free( omega );
	free( ctr ); free( qbox ); free( nqbox ); free( qx );
	free( size ); free( index );
	free( ev ); free( eig );
	free( ltg );

	return 0;
}
예제 #4
0
int main( int argc, char **argv )
{
	/* Basic variables */
	int i,j,k,p,m;
	int dim = 2;
	int deg = 3;
	int pdim = binomial( dim + deg, dim );
	int plm = 0;
	int radn = 10;
	int nnz;
	int ret,ns;
	double zrt = 1e-6;
	double sum;
	double xx,res;
	double tol = zrt;
	double sft = 0.0;
	int neig = 100;
	double *ev = (double*) malloc( 2 * neig * sizeof(double) );
	double *alpha = (double*) malloc( ( neig + 3 ) * sizeof(double) );
	double *beta = (double*) malloc( ( neig + 3 ) * sizeof(double) );
	double *gamma = (double*) malloc( ( neig + 3 ) * sizeof(double) );

	/* Switches */
	int b_sft = 0; /* Use argument as shift */
	int b_prj = 0; /* Build projected system matrices */
	int b_pc = 0; /* Build a preconditioner */
	int b_grd = 0; /* Load points from grid file */
	int b_ext = 0; /* Load external potential */

	/* Other stuff */
	char gfn[1024];
	FILE *fp;
	rkp_t rk;
	nuclei_t ext;
	symtab_t sym;
	symbol_t ss;

	/* Take in the options */
	int optc;
	while( ( optc = getopt( argc, argv, "C:g:d:s:t:S:r:x:pPc" ) ) != -1 )
        {
                switch( optc )
                {
			case 'C':
				symtab_init( &sym, 1024 );
				cfgread_load_symbols_f( optarg, &sym );
				symtab_print( &sym );
				break;
			case 'r':
				radn = atoi( optarg );
				break;
			case 'c':
				b_pc = 1;
				break;
			case 'd':
				deg = atoi( optarg );
				break;
			case 't':
				tol = atof( optarg );
				break;
			case 'S':
				sft = atof( optarg );
				b_sft = 1;
				break;
			case 'p':
				plm = 1;
				break;
			case 'P':
				b_prj = 1;
				break;
			case 'g':
				b_grd = 1;
				strcpy( gfn, optarg );
				break;
			case 'x':
				b_ext = 1;
				load_nuclei( optarg, &ext, 0 );
				nuclei_print( &ext );
				break;
			case '?':
			default:
				fprintf( stderr, "I don't understand the jibberish you are spouting. Goodbye.\n" );
				return 0;
				break;
		}
	}
	if( !b_ext )
	{
		fprintf( stderr, "Please specify an external potential. Exiting.\n" );
		return 0;
	}

	/* Allocate and generate grid points */
	int nb;
	int npts;
	double *pts,*dlt,*val,*gqw;

	/* Load points from file if switch is set */
	if( b_grd )
	{
		fprintf( stderr, "Loading points from file... " );
		load_points( gfn, &dim, &npts, &pts, 0 );
		fprintf( stderr, "dim = %d npts = %d. Done.\n", dim, npts );
		fflush( stderr );
	}

	/* Set up the plot points */
        int pgx = 70;
        int pgy = 70;
        double x = 5.0;
        double y = 5.0;
        double pdx = x / (double) ( pgx - 1 );
        double pdy = y / (double) ( pgy - 1 );
        int nppts = pgx * pgy;
        double *ppts = (double*) malloc( nppts * dim * sizeof(double) );
        for(i=0;i<pgx;i++)
                for(j=0;j<pgy;j++)
                        ppts[i*pgy*dim+j*dim+0] = (double) i * pdx,
                        ppts[i*pgy*dim+j*dim+1] = (double) j * pdy;

	/* Generate supports */
	dlt = (double*) malloc( npts * sizeof(double) );
	val = (double*) malloc( npts * sizeof(double) );
	gqw = (double*) malloc( npts * sizeof(double) );
	generate_cloud_supports_min( 2, npts, pts, radn, 1.05, dlt, 0.001 );
	for(i=0;i<npts;i++)
                gqw[i] = 1.0;

	/* Build variables */
	double f,g,r,s,rr,a,b;
	double *vv,*ww,*pc,*xv,*xvh,*rv,*rvh,*rrv,*rrvh,*pv,*pvh; /* Variables for CG iteration */
	double *amat,*bmat,*cmat,*cmatt,*smat,*tmat,*temp,*dv,*rhs;
	long *iamat,*jamat,*ibmat,*jbmat,*icmat,*jcmat,*icmatt,*jcmatt,*ismat,*jsmat,*itmat,*jtmat,*list;

	/* Calculate the number of non-zeros */
	for(nnz=0,i=0;i<npts;i++)
	{
		for(j=0;j<npts;j++)
		{
			xx = 0.0;
			for(k=0;k<dim;k++)
				xx += pow( pts[i*dim+k] - pts[j*dim+k], 2.0 );
			if( xx < pow( dlt[j], 2.0 ) )
				++nnz;
		}
	}
	fprintf( stderr, "nnz = %5d\n", nnz );
	nnz = nnz + 1;

	/* Allocate this stuff static for now, but make dynamic ASAP */
	iamat = (long*) malloc( ( npts + 1 ) * sizeof(long) );
	jamat = (long*) malloc( nnz * sizeof(long) );
	ibmat = (long*) malloc( ( npts + 1 ) * sizeof(long) );
	jbmat = (long*) malloc( nnz * sizeof(long) );
	icmat = (long*) malloc( ( npts + 1 ) * sizeof(long) );
	jcmat = (long*) malloc( nnz * sizeof(long) );
	icmatt = (long*) malloc( ( npts + 1 ) * sizeof(long) );
	jcmatt = (long*) malloc( nnz * sizeof(long) );
	ismat = (long*) malloc( ( npts + 1 ) * sizeof(long) );
	jsmat = (long*) malloc( npts * npts * sizeof(long) );
	itmat = (long*) malloc( ( npts + 1 ) * sizeof(long) );
	jtmat = (long*) malloc( npts * npts * sizeof(long) );
	list = (long*) malloc( ( npts + 1 ) * sizeof(long) );
	temp = (double*) malloc( ( npts + 1 ) * sizeof(double) );

	/* Allocate stuff; can't use stack for this garbage!!! */
	vv = (double*) malloc( npts * npts * sizeof(double) );
        ww = (double*) malloc( npts * npts * sizeof(double) );
	pc = (double*) malloc( npts * sizeof(double) );
	xv = (double*) malloc( npts * sizeof(double) );
	xvh = (double*) malloc( npts * sizeof(double) );
	rv = (double*) malloc( npts * sizeof(double) );
	rvh = (double*) malloc( npts * sizeof(double) );
	rrv = (double*) malloc( npts * sizeof(double) );
	rrvh = (double*) malloc( npts * sizeof(double) );
	pv = (double*) malloc( npts * sizeof(double) );
	pvh = (double*) malloc( npts * sizeof(double) );

	/* Allocate matrix storage */
	amat = (double*) malloc( nnz * sizeof(double) );
	bmat = (double*) malloc( nnz * sizeof(double) );
	cmat = (double*) malloc( nnz * sizeof(double) );
	cmatt = (double*) malloc( nnz * sizeof(double) );
	smat = (double*) malloc( npts * npts * sizeof(double) );
	tmat = (double*) malloc( npts * npts * sizeof(double) );
	rhs = (double*) malloc( npts * sizeof(double) );
	dv = (double*) malloc( npts * sizeof(double) );

	/* Initialize the RKP basis */
	rkp_init( &rk, npts, dim, deg, pts, dlt, gqw, val, cubic, 1.0 );
	rkp_basis_generate_scaled_const( &rk );
	rkp_wavelet_basis_generate_scaled_const( &rk );

	/* Form the Laplace operator correctly with wavelets */
	int ord[2] = { 2, 4 }; /* Indexes which contain the xx and yy second derivatives */

	/* Build the matrices here to simplify things as much as possible */
	for(i=0;i<nnz;i++) /* Don't need this many entries anymore */
		amat[i] = 0.0, bmat[i] = 0.0;
	for(i=0;i<npts;i++)
		iamat[i] = -1, ibmat[i] = -1;
	for(p=0,i=0;i<npts;i++)
	{
		for(j=0;j<npts;j++)
		{
			/* Check to see if window function at j is large enough to be nonzero */
			xx = 0.0;
			for(k=0;k<dim;k++)
				xx += pow( pts[i*dim+k] - pts[j*dim+k], 2.0 );
			if( xx > pow( dlt[j] * rk.wrad, 2.0 ) )
				continue;
			if( iamat[i] == -1 )
				iamat[i] = p; /* The beginning of row i entries in amat */
			if( ibmat[i] == -1 )
				ibmat[i] = p;
			jamat[p] = j;
			jbmat[p] = j;
			for(k=0;k<dim;k++)
				amat[p] -= 2.0 * 0.5 * gqw[j] * rkp_wavelet_term_evaluate_node_scaled_const( &rk, j, ord[k], i ) / dlt[i] / dlt[i];
			amat[p] += gqw[j] * rkp_term_evaluate_node_scaled_const( &rk, j, i ) * coulomb_potential( dim, pts + i * dim, ext.np, ext.pts );
			bmat[p] = gqw[j] * rkp_term_evaluate_node_scaled_const( &rk, j, i );
			++p;
		}
	}
	iamat[npts] = p;
	ibmat[npts] = p;

	/* Save some garbage in case dumb shit happens */
	smsave( "amat.oct", npts, npts, iamat, jamat, amat, 1 );
	smsave( "bmat.oct", npts, npts, ibmat, jbmat, bmat, 1 );

	fprintf( stderr, "nnz = %d\n", p );
	fflush( stderr );

	/* Generate a random initial state vector */
	srand((unsigned)time(0));

	/* Count the number of boundary nodes */
	nb = 0;
	for(i=0;i<npts;i++)
		if( on_boundary( pts + i * dim ) == 1 )
			++nb;

	/* QR factorization first */
	fprintf( stderr, "Running QR factorization... " );
	fflush( stderr );
        eigenvalue_qrfactorize( dim, npts, pts, ibmat, jbmat, bmat, rhs, vv );
	fprintf( stderr, "Done.\n" );
	fflush( stderr );

	/* Now build the subspace projection matrix */
	fprintf( stderr, "Building subspace projection matrix... " );
	fflush( stderr );
	eigenvalue_subprojmat( npts, nb, vv, ww );
	fprintf( stderr, "Done.\n" );
	fflush( stderr );

	/* Save the projection matrix */
	msave( "wmat.oct", npts - nb, npts, ww, 1 );

	/* Build smat and tmat */
	fprintf( stderr, "Building smat and tmat... " );
	fflush( stderr );
	sparse_symbmm( (long) npts, (long) npts, (long) npts,
		ibmat, jbmat, iamat, jamat, ismat, jsmat, list );
	sparse_dgemm( (long) npts, (long) npts, (long) npts,
		ibmat, jbmat, bmat, iamat, jamat, amat, ismat, jsmat, smat, temp );
	sparse_symbmm( (long) npts, (long) npts, (long) npts,
		ibmat, jbmat, ibmat, jbmat, itmat, jtmat, list );
	sparse_dgemm( (long) npts, (long) npts, (long) npts,
		ibmat, jbmat, bmat, ibmat, jbmat, bmat, itmat, jtmat, tmat, temp );
	fprintf( stderr, "Done.\n" );
	fflush( stderr );

	/* Initialize to a normalized random vector */
	eigenvalue_initialize( npts, rhs );

	/* Now subtract out all vectors in vv from rhs */
        eigenvalue_project( npts, nb, vv, rhs );

	/* Normalize first using tmat */
	eigenvalue_normalize( npts, itmat, jtmat, tmat, rhs, temp );

	/* Initialize the preconditioner to the identity */
        for(i=0;i<npts;i++)
                pc[i] = 1.0;

	/* Solve the eigenvalue problem actually */
	fprintf( stderr, "\n" );
	fprintf( stderr, "Solving Jacobi-Davidson method:\n" );
	eigenvalue_solver( npts, iamat, jamat, amat, ibmat, jbmat, bmat, icmat, jcmat, cmat,
				icmatt, jcmatt, cmatt, ismat, jsmat, smat, itmat, jtmat, tmat,
				rv, rvh, rrv, rrvh, pv, pvh, xv, xvh, dv, pc, rhs, temp, r, tol,
				nb, b_pc, -0.145, vv );

	/* Attempt constrained sparse generalized unsymmetric Lanczos biorthogonalization to solve for bottom few eigenvalues */
	fprintf( stderr, "\n" );
	fprintf( stderr, "Solving with constrained Lanczos method:\n" );
	csgulanczoslp( npts, neig, iamat, jamat, amat, ibmat, jbmat, bmat, alpha, beta, gamma, NULL, NULL, nb, vv, 1e-10, 200, 0, &ret );
	//csgulanczoslp( npts, neig, ibmat, jbmat, bmat, iamat, jamat, amat, alpha, beta, gamma, NULL, NULL, nb, vv, 1e-10, 1000, 0, &ret );
	//sgulanczos( npts, neig, iamat, jamat, amat, ibmat, jbmat, bmat, alpha, beta, gamma, NULL, NULL, 1e-10, 200, 0, &ret );
	fprintf( stderr, "lanczos ret = %d\n", ret );
	treigtridqds( neig, alpha + 1, beta + 1, gamma + 1, 100000, ev, &ret, &ns );
	complex_bubble_sort( neig, ev );
        fprintf( stderr, "Reduction = %d Steps = %d\n", ret, ns );
        for(i=0;i<neig;i++)
                fprintf( stderr, "%15.7f+%15.7fi\n", ev[2*i+0], ev[2*i+1] );

	/* Calculate actual eigenvalue */
	eigenvalue_calculate( npts, iamat, jamat, amat, ibmat, jbmat, bmat, rhs, temp, &f );
	fprintf( stderr, "RQ = %15.7f\n", f );

	/* Copy the solution into the rk structure */
	for(i=0;i<npts;i++)
		rk.vals[i] = rhs[i];

	/* Output the function */
	if( plm )
	{
		fp = fopen( "plot", "w" );
		for(i=0;i<pgx*pgy;i++)
                {
                        fprintf( fp, "%15.7f%15.7f%15.7f\n", ppts[i*dim+0], ppts[i*dim+1], rkp_evaluate_scaled_const( &rk, ppts + i * dim, 0.2 ), 0.1 );
                        if( ( i + 1 ) % pgy == 0 )
                                fprintf( fp, "\n" );
                }
		fclose( fp );
	}
	else
	{
		fp = fopen( "plot", "w" );
		for(i=0;i<npts;i++)
			fprintf( fp, "%15.7f%15.7f%15.7f\n", pts[i*dim+0], pts[i*dim+1], rkp_evaluate_node_scaled_const( &rk, i ) );
	}

	free( pts );
	free( dlt );
	free( val );
	free( gqw );
	free( ppts );

	return 0;
}