void mexFunction( int nOutputArgs, mxArray *outputArgs[], int nInputArgs, const mxArray * inputArgs[])
{	
	if( nInputArgs > 3 ) // Check the number of arguments
		mexErrMsgTxt("Too many input arguments.");
	if (nOutputArgs > 1)
		mexErrMsgTxt("Too many output arguments.");
	
	if(!IS_REAL_2D_FULL_DOUBLE(inputArgs[0])) // Check A
		mexErrMsgTxt("A must be a real 2D full double array.");
	
	int M = mxGetM(inputArgs[0]);
	int N = mxGetN(inputArgs[0]);

	// Create the input matrix W as Eigen Matrix mapping the input matrix
	Eigen::Map<Eigen::MatrixXd> W( mxGetPr(inputArgs[0]) ,M,N);
	// Allocate space for the output matrix G
	Eigen::MatrixXd G = localWeighting(W,true,true); // Implementazione corretta, restituisce i risultati giusti
	//std::cout << G << std::endl;
	outputArgs[0] = mxCreateDoubleMatrix(M,N,mxREAL);
	memcpy(mxGetPr(outputArgs[0]), G.data(), sizeof(double)*M*N);
	return;
}
// mexCalcMutInfDelay
void mexFunction( mwIndex  nlhs, mxArray *plhs[],  mwIndex  nrhs, const mxArray *prhs[])
 {
 /* Macros for the ouput and input arguments */
    #define B_OUT plhs[0]
	#define ARRAY_IN prhs[0]
	#define TAU_IN prhs[1]
	#define BIN_IN prhs[2]
	double *B,  *array, info;
	mwIndex  Nx, nn, i, j, tau, tauMax, Mx;
	if(nrhs < 1 || nrhs > 3) /* Check the number of arguments */
	    mexErrMsgTxt("Wrong number of input arguments.");
	else if(nlhs > 1)
		mexErrMsgTxt("Too many output arguments.");
		
	if(!IS_REAL_2D_FULL_DOUBLE(ARRAY_IN)) /* Check A */
		mexErrMsgTxt("A must be a real 2D full double array.");
	
	// get the input array dimensions and the pointer
	Mx = (mwIndex) mxGetM(ARRAY_IN); /* Get the dimensions */
	Nx = (mwIndex) mxGetN(ARRAY_IN);
	array = mxGetPr(ARRAY_IN);  /* Get the pointer to the data of A */
	
	if(nrhs < 2) /* If p is unspecified, set it to a default value */
	  	tauMax = min(20, Mx-5);
	else /* If P was specified, check that it is a real double scalar */
		if(!IS_REAL_SCALAR(TAU_IN) )
		        mexErrMsgTxt("tau_max must be a real double scalar.");
		else
       			tauMax = ( mwIndex ) mxGetScalar( TAU_IN ); /* Get tauMax */
	if(nrhs < 3) /* If p is unspecified, set it to a default value */
	  	bin = -1;
	else /* If P was specified, check that it is a real double scalar */
		if(!IS_REAL_SCALAR(BIN_IN) )
		    mexErrMsgTxt("tau_max must be a real double scalar.");
		else
			bin = ( mwIndex )mxGetData( BIN_IN ); /* Get bin number */


	B_OUT = mxCreateDoubleMatrix( (mwSize)tauMax+1, (mwSize)Nx, mxREAL); /* Create the output matrix */
	B = mxGetPr(B_OUT); /* Get the pointer to the data of B */
 	
	/*----- done reading in data -----*/

	logtwo = 1.0/log(2.0);

	// mexPrintf("Nx:\t%u\tM:\t%u\n\n", Nx, Mx);
	
for (nn = 0; nn<Nx; nn++) { // a loop through the second dimension

	n0 = 1;
	while ((n0+tauMax)<= Mx)  n0 *= 2;
	n0 /= 2;

	/* n0 = Mx - tauMax; */
	j = n0;
	for (i=0; i<KMAX;i++)  {
		pow2[i] = j;
		j /= 2;
	}
	// mmax = (( mwIndex )(log(((float)n0))*logtwo+0.1));
	// mexPrintf( "n0: %d mmax: %d\n", n0, mmax);

	for (i=0; i<n0;i++)  {
		pop[i] = array[i + (Mx)*nn];
		// mexPrintf("Nx*nn\t%u\tu:\t%u\tpop:\t%f\n", (Mx)*nn, i, pop[i]);
		pindex[i] = i;		
	}
	saneqsort(0, n0-1);
	/* for (i=0;i<Mx-tauMax;i++)  s[pindex[i]] = i; */
	/* WARNING!!!!!! Note that this definition is somewhat opposite
	 * of what 'makes sense' but will make number() routine faster */
	for (i=0;i<n0;i++)  s[i] = pindex[i]; // s[i + (tauMax+1)*nn] = pindex[i + (tauMax+1)*nn];  //

	for (tau=0;tau<=tauMax;tau++)  {
		/* now do tau offset for q[] array */
		for (i=tau; i<tau+n0; i++)  {
			pop[i-tau] = array[i + (Mx)*nn];
			pindex[i-tau] = i-tau;			
		}
		
		saneqsort(0, n0-1);
		
		for (i=0;i<n0;i++)		q[pindex[i]] = i;
		/* for (i=0;i<n0;i++)  fprintf(stderr,"%d ",q[i]); */
		/* fprintf(stderr,"\n"); */


		/* assume at this time that s[], q[] contain integers from
		 * 0 to 2^Nx-1.   q[] is based on the time lagged data from
		 * array[].  s[] is just array[].
		 *
		 * example: s[] = 0 4 5 3 6 1 2 7
		 *          q[] = 7 4 5 3 6 2 0 1
		 *
		 *     o.......      so the first partition is s: 0-3 | 4-7
		 *     ......o.                                q: 0-3 | 4-7
		 *     .....o..
		 *     ....o...      with 3 in LL, 1 in UL, 3 in UR, 1 in LR
		 *     ...o....      quadrants.
		 *     .o......
		 *     .......o      second partition is s: 01 | 23 | 45 | 67
		 *     ..o.....                          q: 01 | 23 | 45 | 67
		 *                   with distribution: 1001
		 *				                    0020
		 *								1100
		 *								0101
		 */

		/* now find I(S,Q) according to formula (19) */
		info = findisq();		
		// mexPrintf("tau = %u\n", tau + (tauMax+1)*nn );
        B[ tau + (tauMax+1)*nn ] = info;
		// printf("%d %f\n",tau,info);
		// fprintf(stderr,"%d %f\n",tau,info);
	}
}
	// exit(0);
}	/* END OF MAIN */
Beispiel #3
0
void mexFunction(int nlhs,mxArray *plhs[], int nrhs, const mxArray *prhs[])  {
    /**********************************************************/
    /*                                                        */
    /*              Initializing the problem                  */
    /*                                                        */
    /**********************************************************/
    #define QH_OUT             plhs[0]
    #define QHexact_OUT        plhs[1]
    #define source_IN          prhs[0]
    #define field_IN           prhs[1]
    #define charge_IN          prhs[2]
    #define nCheb_IN           prhs[3]
    #define level_IN           prhs[4]
    #define L_IN               prhs[5]
    #define use_cheby_IN       prhs[6]
    #define singular_IN        prhs[7]  
   
    
    // Check number of argument
    if(nrhs != 7) {
        mexErrMsgTxt("Wrong number of input arguments");
    }else if(nlhs > 2){
        mexErrMsgTxt("Too many output arguments");
    }
    
    if( !IS_REAL_2D_FULL_DOUBLE(source_IN)) {
        mexErrMsgTxt("Third input argument is not a real 2D full double array.");
    }
    if( !IS_REAL_2D_FULL_DOUBLE(field_IN)) {
        mexErrMsgTxt("Third input argument is not a real 2D full double array.");
    }
    if( !IS_REAL_2D_FULL_DOUBLE(charge_IN)) {
        mexErrMsgTxt("Third input argument is not a real 2D full double array.");
    }
    if( !IS_REAL_SCALAR(nCheb_IN)){
        mexErrMsgTxt("nChebnotes must be a real double scalar");
    }
    if( !IS_REAL_SCALAR(level_IN)){
        mexErrMsgTxt("level must be a real double scalar");
    }
    if( !IS_REAL_SCALAR(L_IN)){
        mexErrMsgTxt("L must be a real double scalar");
    }
    if( !IS_REAL_SCALAR(use_cheby_IN)){
        mexErrMsgTxt("use_cheby must be a real double scalar");
    }



    double L = *mxGetPr(L_IN);         // Length of simulation cell (assumed to be a cube)
    int n = *mxGetPr(nCheb_IN);        // Number of Chebyshev nodes per dimension
    doft dof;
    dof.f   = 1;
    dof.s   = 1;
    int Ns = mxGetM(source_IN);        // Number of sources in simulation cell
    int Nf = mxGetM(field_IN);         // Number of field points in simulation cell
    int m  = mxGetN(charge_IN);        // Number of r.h.s.
    int level = *mxGetPr(level_IN);
    double eps = 1e-9;
    int use_chebyshev = *mxGetPr(use_cheby_IN);
        
    vector3* source = new vector3[Ns];    // Position array for the source points
    vector3* field = new vector3[Nf];     // Position array for the field points

    read_data(source_IN, field_IN, Ns, Nf, source, field);
    
    double * charges;
    charges = mxGetPr(charge_IN);

    double err;
    QH_OUT = mxCreateDoubleMatrix(Nf*dof.f, m, mxREAL);
    double* stress = mxGetPr(QH_OUT);

    
    /**********************************************************/
    /*                                                        */
    /*                 Fast matrix vector product             */
    /*                                                        */
    /**********************************************************/
    
    mexPrintf("\nStarting FMM computation...\n");

    /*****      Pre Computation     ******/
    clock_t  t0 = clock();
    kernel_Exp Atree(&dof,L,level, n, eps, use_chebyshev);
	//myKernel Atree(&dof,L,level, n, eps, use_chebyshev);
    Atree.buildFMMTree();
    clock_t t1 = clock();
    double tPre = t1 - t0;
    
    /*****      FMM Computation     *******/
    t0 = clock();
    //H2_3D_Compute<myKernel> compute(&Atree, field, source, Ns, Nf, charges,m, stress);
    H2_3D_Compute<kernel_Exp> compute(&Atree, field, source, Ns, Nf, charges,m, stress);
    
	t1 = clock();
    double tFMM = t1 - t0;
    
    

    /**********************************************************/
    /*                                                        */
    /*              Exact matrix vector product               */
    /*                                                        */
    /**********************************************************/
    
    mexPrintf("\nPre-computation time: %.4f\n",double(tPre) / double(CLOCKS_PER_SEC));
    mexPrintf("FMM computing time: %.4f\n",double(tFMM) / double(CLOCKS_PER_SEC));
    mexPrintf("FMM total time: %.4f\n",double(tFMM+tPre) / double(CLOCKS_PER_SEC));
    if (nlhs == 2) {
        mexPrintf("\nStarting direct computation...\n");
        t0 = clock();
        QHexact_OUT = mxCreateDoubleMatrix(Nf*dof.f, m, mxREAL);
        double* stress_dir = mxGetPr(QHexact_OUT);

        DirectCalc3D(&Atree, field, Nf, source, charges, m, Ns, &dof,0 , L, stress_dir);
        t1 = clock();
        double tExact = t1 - t0;
        mexPrintf("Exact computing time: %.4f\n",double(tExact) / double(CLOCKS_PER_SEC));
        // Compute the 2-norm error
        err = ComputeError(stress,stress_dir,Nf,&dof,m);
        mexPrintf("Relative Error: %e\n",err);
    }

    /*******            Clean Up        *******/
    delete []source;
    delete []field;
    return;
}