Exemplo n.º 1
0
Arquivo: example.c Projeto: ombt/ombt
// test driver
main(int , char **)
{
    // output precision
    cout.precision(6);
    cout.setf(ios::showpoint);

    // define matrix and initialize elements
    int nrows = 3;
    int ncols = 3;
    int idata = 0;
    int ir = 0;
    Matrix<double> m(nrows, ncols);
    for ( ; ir < nrows; ir++)
    {
        for (int ic = 0; ic < ncols; ic++)
        {
            m(ir, ic) = data[idata++];
        }
    }
    cout << "TEST MATRIX IS ... " << endl;
    cout << m << endl;
    Matrix<double> msave(m);

    // initialize inhomogeneous part.
    Vector<double> y(nrows);
    for (ir = 0; ir < nrows; ir++)
    {
        y[ir] = data[idata++];
    }
    cout << "TEST Y-VECTOR IS ... " << endl;
    cout << y << endl << endl;

    // get LUP decomposition
    Vector<int> pv(nrows);
    double determinant;
    MustBeTrue(GaussianLUP_Pivot(m, pv, 0.0, determinant) == OK);

    // get solution using LUP results
    Vector<double> x(nrows);
    MustBeTrue(SolveUsingGaussianLUP_Pivot(m, x, y, pv, 0.0) == OK);
    cout << "SOLUTION X IS ... " << x << endl << endl;

    // get inverse using LUP results
    Matrix<double> minv(nrows, ncols);
    MustBeTrue(GetInverseUsingGaussianLUP_Pivot(m, minv, pv, 0.0) == OK)
    cout << "INVERSE OF M IS ... " << endl << endl;
    cout << minv << endl;
    cout << "M*MINV IS ... " << endl;
    cout << msave*minv << endl << endl;

    return(0);
}
Exemplo n.º 2
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;
}