int main( ) { Lgm_ElapsedTimeInfo t; Lgm_CTrans *c = Lgm_init_ctrans( 1 ); // more compact declaration Lgm_QinDentonOne p; Lgm_MagModelInfo *mInfo; Lgm_Vector *u, *B, q, v; double Time, JD, x, y, z, r, d, dist; long int Date, n; Lgm_Octree *Octree; Lgm_OctreeData *kNN; int K, Kgot, i, j; t.ColorizeText = TRUE; Lgm_ElapsedTimeInit( &t, 255, 150, 0 ); LGM_ARRAY_1D( u, 5000000, Lgm_Vector ); LGM_ARRAY_1D( B, 5000000, Lgm_Vector ); mInfo = Lgm_InitMagInfo( ); Date = 20020713; // August 12, 2004 Time = 18.0 + 0.0/60.0 + 30.0/3600.0; // Universal Time Coordinated (in decimal hours) JD = Lgm_Date_to_JD( Date, Time, c ); // Compute JD // Get (interpolate) the QinDenton vals from the values in the file at the given Julian Date Lgm_get_QinDenton_at_JD( JD, &p, 0 ); Lgm_Set_Coord_Transforms( Date, Time, mInfo->c ); Lgm_set_QinDenton( &p, mInfo ); mInfo->Bfield = Lgm_B_T89; d = 0.3; n = 0; Lgm_PrintCurrentTime( &t ); for ( x = -15.0; x <= 15.0; x += d ){ for ( y = -15.0; y <= 15.0; y += d ){ for ( z = -15.0; z <= 15.0; z += d ){ u[n].x = x; u[n].y = y; u[n].z = z; r = Lgm_Magnitude( &u[n] ); //if (r > 1.1){ // mInfo->Bfield( &u[n], &B[n], mInfo ); ++n; //} } } } Lgm_PrintElapsedTime( &t ); printf("n = %ld\n", n); /* * Test kNN algorithm. */ printf("Creating Octree\n"); Lgm_ElapsedTimeInit( &t, 255, 150, 0 ); Octree = Lgm_InitOctree( u, B, n ); printf("Min, Max, Diff = %g %g %g\n", Octree->Min, Octree->Max, Octree->Diff); Lgm_PrintElapsedTime( &t ); q.x = 3.2233; q.y = 2.4698; q.z = 1.35193; K = 4; LGM_ARRAY_1D( kNN, K, Lgm_OctreeData ); printf("\n\nTesting kNN (1000000 times)\n"); Lgm_ElapsedTimeInit( &t, 255, 150, 0 ); for (j=0; j<=1000000; j++){ q.x = 30.0*rand()/(double)RAND_MAX - 15.0; q.y = 30.0*rand()/(double)RAND_MAX - 15.0; q.z = 30.0*rand()/(double)RAND_MAX - 15.0; Lgm_Octree_kNN( &q, Octree, K, &Kgot, 1.0*1.0, kNN ); } Lgm_PrintElapsedTime( &t ); printf("\n\nKgot = %d q = %g %g %g\n", Kgot, q.x, q.y, q.z); for (i=0; i<Kgot; i++){ Lgm_OctreeUnScalePosition( &(kNN[i].Position), &v, Octree ); Lgm_OctreeUnScaleDistance( sqrt(kNN[i].Dist2), &dist, Octree ); printf("%02d: dist = %g v = %g %g %g\n", i, dist, v.x, v.y, v.z ); } LGM_ARRAY_1D_FREE( kNN ); printf("Freeing Octree\n"); Lgm_ElapsedTimeInit( &t, 255, 150, 0 ); Lgm_FreeOctree( Octree ); printf("Octree Freed\n"); Lgm_PrintElapsedTime( &t ); Lgm_free_ctrans( c ); Lgm_FreeMagInfo( mInfo ); LGM_ARRAY_1D_FREE( u ); LGM_ARRAY_1D_FREE( B ); return(0); }
/** From a vector-field dataset, compute the vector-valued weighting factors, * \f$\vec{c}_j\f$. Info is returned in the rbf structure. * * * \param[in] v - pointer to an array of position vectors. * \param[in] B - pointer to array of corresponding field vectors. * \param[in] n - number of (v, B) pairs defined. * \param[in] eps - smoothing factor in scalar RBF. * \param[in] RadialBasisFunction - RBF to use. Can be LGM_RBF_GAUSSIAN, LGM_RBF_MULTIQUADRIC * * \return pointer to structure containing info for RBF interpolation. User * is responsible for freeing with Lgm_DFI_RBF_Free(). * * \author M. G. Henderson * date January 24, 2012 * * */ Lgm_DFI_RBF_Info *Lgm_DFI_RBF_Init( unsigned long int *I_data, Lgm_Vector *v, Lgm_Vector *B, int n, double eps, int RadialBasisFunction ) { int i, j, ii, jj, p, q, n3, s; double *d, **a, Phi[3][3], val; gsl_matrix *A, *V; gsl_vector *D, *c, *S, *Work; Lgm_DFI_RBF_Info *rbf; n3 = 3*n; A = gsl_matrix_calloc( n3, n3 ); c = gsl_vector_alloc( n3 ); D = gsl_vector_calloc( n3 ); /* * Save info needed to do an evaluation. */ rbf = ( Lgm_DFI_RBF_Info *)calloc( 1, sizeof(*rbf) ); rbf->RadialBasisFunction = RadialBasisFunction; rbf->eps = eps; rbf->n = n; rbf->n3 = n3; LGM_ARRAY_1D( rbf->LookUpKey, n, unsigned long int); LGM_ARRAY_1D( rbf->v, n, Lgm_Vector); LGM_ARRAY_1D( rbf->c, n, Lgm_Vector); for ( i=0; i<n; i++ ) { rbf->LookUpKey[i] = I_data[i]; rbf->v[i] = v[i]; } // This subtraction doesntm seem to work out very well... // rbf->Bx0 = B[0].x; // rbf->By0 = B[0].y; // rbf->Bz0 = B[0].z; double Bbkg; for ( Bbkg = 0.0, i=0; i<n; i++ ) Bbkg += B[i].x; rbf->Bx0 = Bbkg/(double)n; for ( Bbkg = 0.0, i=0; i<n; i++ ) Bbkg += B[i].y; rbf->By0 = Bbkg/(double)n; for ( Bbkg = 0.0, i=0; i<n; i++ ) Bbkg += B[i].z; rbf->Bz0 = Bbkg/(double)n; rbf->Bx0 = 0.0; rbf->By0 = 0.0; rbf->Bz0 = 0.0; /* * Fill d array. (Subtract off the field at the nearest point v[0] -- See * McNally [2011].) We add this field back on later. */ for (i=0; i<n; i++){ gsl_vector_set( D, 3*i+0, B[i].x - rbf->Bx0 ); gsl_vector_set( D, 3*i+1, B[i].y - rbf->By0 ); gsl_vector_set( D, 3*i+2, B[i].z - rbf->Bz0 ); } /* * [ row0 ] * Fill A matrix. In C, order is A[row][col] = [ row1 ] * [ row2 ] */ for ( i=0; i<n; i++ ) { // locate start row for subarray ii = 3*i; for ( j=0; j<n; j++ ) { // locate start column for subarray jj = 3*j; // Get Phi( v_i - v_j ) Lgm_DFI_RBF_Phi( &v[i], &v[j], Phi, rbf ); for ( p=0; p<3; p++ ){ // subarray row for ( q=0; q<3; q++ ){ // subarray column gsl_matrix_set( A, ii+p, jj+q, Phi[p][q] ); } } } } /* for (i=0; i<n; i++ ) { printf("v%02d = %8g %8g %8g B%02d = %8g %8g %8g\n", i, v[i].x, v[i].y, v[i].z, i, B[i].x, B[i].y, B[i].z ); } for (i=0; i<n3; i++){ for (j=0; j<n3; j++){ printf("%8g ", gsl_matrix_get(A, i, j ) ); } printf("\n"); } */ /* * Now we need to solve the system of equation; * * d = ac * * for c. * * First create gsl_vector and gsl_matrix views of the d and A arrays. * Then compute Cholesky decomposition of the a array. Then solve the * system to get c. * */ if ( LGM_DFI_RBF_SOLVER == LGM_CHOLESKY_DECOMP ){ gsl_linalg_cholesky_decomp( A ); gsl_linalg_cholesky_solve( A, D, c ); } else if ( LGM_DFI_RBF_SOLVER == LGM_PLU_DECOMP ){ gsl_permutation *P = gsl_permutation_alloc( n3 ); gsl_linalg_LU_decomp( A, P, &s ); gsl_linalg_LU_solve( A, P, D, c ); gsl_permutation_free( P ); } else if ( LGM_DFI_RBF_SOLVER == LGM_SVD ){ V = gsl_matrix_calloc( n3, n3 ); S = gsl_vector_alloc( n3 ); Work = gsl_vector_alloc( n3 ); gsl_linalg_SV_decomp( A, V, S, Work ); gsl_linalg_SV_solve( A, V, S, D, c ); gsl_vector_free( Work ); gsl_vector_free( S ); gsl_matrix_free( V ); } for (i=0; i<n; i++){ rbf->c[i].x = gsl_vector_get( c, 3*i+0 ); rbf->c[i].y = gsl_vector_get( c, 3*i+1 ); rbf->c[i].z = gsl_vector_get( c, 3*i+2 ); } gsl_vector_free( D ); gsl_vector_free( c ); gsl_matrix_free( A ); return( rbf ); }