Example #1
0
int eigen_sym_core(double *mat, int n, double *eval) {
	double **a;
	int i, j;
	double *off_diag;

	a = (double **) malloc(n * sizeof(double*));
	for (i = 0; i < n; i++)
		a[i] = (double *) calloc(n, sizeof(double));
	off_diag = (double *) malloc(n * sizeof(double*));
	
	for (i = 0; i < n; i++)
		for (j = 0; j < n; j++)
			a[i][j] = mat[i*n+j];

	/* make this matrix tridiagonal */
	tred2(a, n, eval, off_diag);
	/* compute eigenvalues and eigenvectors */
	tqli(eval, off_diag, n, a);

	free(off_diag);
	for (i = n-1; i >= 0; i--)
		free(a[i]);
	free(a);

	return 0;
}
int maxentmc_symmeig(size_t const n, maxentmc_float_t * const A, size_t const tda, maxentmc_float_t * const eigval)
{

    if(n==0 || tda==0){
        MAXENTMC_MESSAGE(stderr,"error: zero matrix size");
        return -1;
    }

    MAXENTMC_CHECK_NULL(A);
    MAXENTMC_CHECK_NULL(eigval);
    maxentmc_float_t temp[n];

    tred2(n, A, tda, eigval, temp);

    int status = tqli(n, A, tda, eigval, temp);

    if(status){
        MAXENTMC_MESSAGE(stderr,"error: too many iterations in tqli");
    }
    else
        eigsrt(n, A, tda, eigval);

    return status;

}
Example #3
0
//---------------------------------------------------------------------------
// DiagonalizeMatrix
//
// Diagonalize a real, symmetric matrix of dimension [1...inDim] by
// computing the eigenvalues and eigenvectors.
//
// Input matrix is destroyed by this routine.
//
// Eigenvalues are sorted in descending order, and stored in output
// array; corresponding Eigenvectors are stored in an output matrix.
// Output arrays must be allocated to the proper dimension prior to
// calling this routine, arrays are addressed using NR convention
// [1...N].
//
// This procedure uses either Jacobi rotation or QL reduction to
// compute the eigenvalues/eigenvectors.  Comment out the appropriate
// section of code for the un-favored algorithm.
//
// plk 3/10/2005
//---------------------------------------------------------------------------
void DiagonalizeFMatrix(float **inMatrix, \
                       int inDim, \
                       float *outEigenValue, \
                       float **outEigenVector)
{
   int nrot;
   float *theE;



   //-----------------------------------------------------------
   // Jacobi rotation algorithm
   //
   //jacobi(inMatrix,inDim,outEigenValue,outEigenVector,&nrot);
   //eigsrt(outEigenValue,outEigenVector,inDim);
   //-----------------------------------------------------------


   //-----------------------------------------------------------
   // QL reduction algorithm
   //
   theE = vector(1,inDim);
   tred2(inMatrix, inDim, outEigenValue, theE);
   tqli(outEigenValue,theE,inDim,inMatrix);
   CopyFMatrix(inMatrix,outEigenVector,\
                1,inDim,\
                1,inDim);
   //----------------------------------------------------------


}
Example #4
0
/* \brief Finds the largest eigenvector of a symmetric matrix
 *
 * Uses Householder reduction (code taken from Numerical Recipes in C)
 *
 * \params  matrix
 *		Matrix pointer (content is modified !)
 *	\params	n
 *		Matrix dimension
 *	\params	e
 *		Largest eigenvector
 */
void largestEigenvector(double *matrix, int n, double *eigenvector)
{
	/* <!> *$€%+§&@ convention of Numerical Recipes to begin index by 1 */

	/* Copy matrix into n*n table */
	int i;
	double **a, *iM;
	double d[n+1]; /* diagonal elements */
	double e[n+1]; /* off-diagonal elements */
	double max; /* maximum eigenvalue */
	int iMax; /* index of maximum eigenvector */

	/* Initialize a and z */
	a = malloc((n+1)*sizeof(double *));
	iM = matrix;
	for (i = 1 ; i <= n ; i++)
	{
		a[i] = malloc((n+1)*sizeof(double));
		memcpy(a[i]+1, iM, n*sizeof(double));
		iM += n;
	}

	/* Householder reduction */
	tred2(a, n, d, e);

	/* QL algorithm */
	tqli(d, e, n, a);

	/* Search eigenvector of maximum eigenvalue */
	max = 0;
	iMax = 1;
	for (i = 1 ; i <= n ; i++)
	{
		if (d[i] > max)
		{
			max = d[i];
			iMax = i;
		}
	}

	/* Return maximum eigenvector */
	max = 0;
	for (i = 0 ; i < n ; i++)
	{
		eigenvector[i] = *(a[i+1] + iMax);
		max += SQR(eigenvector[i]);
	}
	max = sqrt(max);
	for (i = 0 ; i < n ; i++)
		eigenvector[i] /= sqrt(max);

	/* release space */
	for (i = 1 ; i <= n ; i++)
	{
		free(a[i]);
	}
	free(a);
}
Example #5
0
int symm_eigen(double *vals, double **A, const int n)
{
   //////////////////////////////////////////////////////////////////
   // it is users' responsibility to make sure that A is symmetric
   ////////////////////////////////////////////////////////////////////
   Vector<double> e(n);
   tred2(A,n,vals,e.begin());
   tqli(vals,e.begin(),n,A);
   return 0;
}
Example #6
0
/*
 * Argument a contains pointers to the rows of a symmetrix matrix.  The
 * in each row is the row number + 1.  These rows are stored in
 * contiguous memory starting with 0.  Evecs also contains pointers to
 * contiguous memory.  N is the dimension.
 */
void
cmat_diag(double**a, double*evals, double**evecs, int n,
              int matz, double tol)
{
  int i,j;
  int diagonal=1;
  double*fv1;

 /* I'm having problems with diagonalizing matrices which are already
  * diagonal.  So let's first check to see if _a_ is diagonal, and if it
  * is, then just return the diagonal elements in evals and a unit matrix
  * in evecs
  */

  for (i=1; i < n; i++) {
    for (j=0; j < i; j++) {
      if (fabs(a[i][j]) > tol) diagonal=0;
      }
    }

  if (diagonal) {
    for(i=0; i < n; i++) {
      evals[i] = a[i][i];
      evecs[i][i] = 1.0;

      for(j=0; j < i; j++) {
        evecs[i][j] = evecs[j][i] = 0.0;
        }
      }
    eigsort(n,evals,evecs);
    return;
    }

  fv1 = (double*) malloc(sizeof(double)*n);
  if (!fv1) {
    fprintf(stderr,"cmat_diag: malloc fv1 failed\n");
    abort();
  }

  for(i=0; i < n; i++) {
      for(j=0; j <= i; j++) {
          evecs[i][j] = evecs[j][i] = a[i][j];
        }
    }

  tred2(n,evecs,evals,fv1,1);

  cmat_transpose_square_matrix(evecs,n);
  tqli(n,evals,evecs,fv1,1,tol);
  cmat_transpose_square_matrix(evecs,n);

  eigsort(n,evals,evecs);

  free(fv1);
  }
Example #7
0
int main(void)
{
	int i,j,k;
	float *d,*e,*f,**a;
	static float c[NP][NP]={
		5.0, 4.3, 3.0, 2.0, 1.0, 0.0,-1.0,-2.0,-3.0,-4.0,
		4.3, 5.1, 4.0, 3.0, 2.0, 1.0, 0.0,-1.0,-2.0,-3.0,
		3.0, 4.0, 5.0, 4.0, 3.0, 2.0, 1.0, 0.0,-1.0,-2.0,
		2.0, 3.0, 4.0, 5.0, 4.0, 3.0, 2.0, 1.0, 0.0,-1.0,
		1.0, 2.0, 3.0, 4.0, 5.0, 4.0, 3.0, 2.0, 1.0, 0.0,
		0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 4.0, 3.0, 2.0, 1.0,
	   -1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 4.0, 3.0, 2.0,
	   -2.0,-1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 4.0, 3.0,
	   -3.0,-2.0,-1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 4.0,
	   -4.0,-3.0,-2.0,-1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0};

	d=vector(1,NP);
	e=vector(1,NP);
	f=vector(1,NP);
	a=matrix(1,NP,1,NP);
	for (i=1;i<=NP;i++)
		for (j=1;j<=NP;j++) a[i][j]=c[i-1][j-1];
	tred2(a,NP,d,e);
	tqli(d,e,NP,a);
	printf("\nEigenvectors for a real symmetric matrix\n");
	for (i=1;i<=NP;i++) {
		for (j=1;j<=NP;j++) {
			f[j]=0.0;
			for (k=1;k<=NP;k++)
				f[j] += (c[j-1][k-1]*a[k][i]);
		}
		printf("%s %3d %s %10.6f\n","eigenvalue",i," =",d[i]);
		printf("%11s %14s %9s\n","vector","mtrx*vect.","ratio");
		for (j=1;j<=NP;j++) {
			if (fabs(a[j][i]) < TINY)
				printf("%12.6f %12.6f %12s\n",
					a[j][i],f[j],"div. by 0");
			else
				printf("%12.6f %12.6f %12.6f\n",
					a[j][i],f[j],f[j]/a[j][i]);
		}
		printf("Press ENTER to continue...\n");
		(void) getchar();
	}
	free_matrix(a,1,NP,1,NP);
	free_vector(f,1,NP);
	free_vector(e,1,NP);
	free_vector(d,1,NP);
	return 0;
}
Example #8
0
//Function utilizing the function tqli() in lib.cpp to calculate eigenvalues and eigenvectors
void tqliEigensolver(double *off_diagonal, double *diagonal, double **output_matrix, int n, double step_length,
                     double omega_r,double(*potential)(double,int,double))
{
    double constant_diagonal = 2./(step_length*step_length);
    double constant_off_diagonal = -1./(step_length*step_length);
    for(int i = 0; i < n; i++){
        diagonal[i] = constant_diagonal+potential(step_length,i+1,omega_r);
        off_diagonal[i] = constant_off_diagonal;
        output_matrix[i][i] = 1;
        for(int j = i + 1; j < n; j++){
            output_matrix[i][j] = 0;
        }
    }
    tqli(diagonal, off_diagonal, n, output_matrix);
}
C_toolbox_eigen_sym::C_toolbox_eigen_sym(/**const*/ double* a, bool yesvec):C_toolbox()
{
    n = 3;
    z = new double*[n];
    z[0] = new double[n];
    z[1] = new double[n];
    z[2] = new double[n];
    z[0][0] = a[0]; z[0][1] = a[1]; z[0][2] = a[2];
    z[1][0] = a[1]; z[1][1] = a[3]; z[1][2] = a[4];
    z[2][0] = a[2]; z[2][1] = a[4]; z[2][2] = a[5];
    d = new double[n];
    e = new double[n];
    yesvecs = yesvec;
    tred2();
    tqli();
    sortEig();
}
Example #10
0
File: rmt.c Project: Phali/libs
void HOE(int n, double **o, long *iseed)
     /* RANDOM ORTOGONAL matrix - from O(N), */
     /* by eigenvectors of a symmetric real matrix-GOE */
     /* that is in turn obtained by P(H)\propto\exp{-Tr(H^2)/2}. */
{
  int i,j,t1,t2;
  double *d,*e,tmp;
  
  d=(double *)malloc(sizeof(double)*n);
  e=(double *)malloc(sizeof(double)*n);
  
  /* get GOE into o[][] */
  GOE(n,o,1,iseed);

  /* shift indices of o[][] */
  for(i=0;i<n;i++) o[i]--;
  
  /* eigenvalues of real symmetric matrix in a */
  tred2(o-1,n,d-1,e-1,1);
  
  tqli(d-1,e-1,n,o-1,1);
  /* eigenvalues are in d[], eigenvec. in a[][] */

  /* free memory - we don't need eigenvalues */
  free(e);
  free(d);

  /* shift o[] back */
  for(i=0;i<n;i++) o[i]++;

  return;

  /* finaly, just for sure, permute eigenvectors - eig. is in column */
  /* n/2 of transpositions */
  for(i=0;i<n/2;i++) {
    /* two random indices */
    t1=rand() % n;
    t2=rand() % n;
    /* switch */
    for(j=0;j<n;j++) {
      tmp=o[j][t1];
      o[j][t1]=o[j][t2];
      o[j][t2]=tmp;
    }
  }
}
Example #11
0
static int eigenvectors(double (*m)[3], double (*evecs)[3], int dim)
{
  double d[3], e[3];
  int i, j, rc;

  for (i=0; i<3; i++){
    for (j=0; j<3; j++){
      evecs[i][j] = m[i][j];
    }
  }

  tred2(evecs, dim, d, e); 

  rc = tqli(d, dim, e, evecs);

  return rc;
}
C_toolbox_eigen_sym::C_toolbox_eigen_sym(/**const*/ double** a, const int nb_rows, bool yesvec):C_toolbox()
{
    n = nb_rows;
    z = new double*[n];
    for(int i=0; i<n ; i++)
    {
        z[i] = new double[n];
        for(int j=0 ; j<n ; j++)
        {
            z[i][j] = a[i][j];
        }
    }
    d = new double[n];
    e = new double[n];
    yesvecs = yesvec;
    tred2();
    tqli();
    sortEig();
}
Example #13
0
void tea_calc_eigenvalues(double *cg_alphas, double *cg_betas,double *eigmin, double *eigmax, int max_iters, int tl_ch_cg_presteps, int *info) {

	int swapped = 0;
  double diag[max_iters+1];
  double offdiag[max_iters+1];
	for (int i = 0; i < max_iters+1; i++ ) {
		diag[i] = 0.0;
		offdiag[i] = 0.0;
	}
  for (int n=1;n <= tl_ch_cg_presteps;n++) {
    diag[n] = 1.0/cg_alphas[n];
    if (n > 1) diag[n] = diag[n] + cg_betas[n-1]/cg_alphas[n-1];
    if (n < tl_ch_cg_presteps) offdiag[n+1] = sqrt(cg_betas[n])/cg_alphas[n];
  }

  tqli(diag, offdiag, tl_ch_cg_presteps, info);

  // ! could just call this instead
  // !offdiag(:)=eoshift(offdiag(:),1)
  // !CALL dsterf(tl_ch_cg_presteps, diag, offdiag, info)

  if (*info != 0) return;

  // bubble sort eigenvalues
  while(true) {
    for (int n = 1; n <= tl_ch_cg_presteps-1; n++) {
      if (diag[n] >= diag[n+1]) {
        double tmp = diag[n];
        diag[n] = diag[n+1];
        diag[n+1] = tmp;
        swapped = 1;
      }
    }
    if (!swapped) break;
    swapped = 0;
  }

  *eigmin = diag[1];
  *eigmax = diag[tl_ch_cg_presteps];

  if (*eigmin < 0.0 || *eigmax < 0.0) *info = 1;
}
Example #14
0
void gaucof(int n, float a[], float b[], float amu0, float x[], float w[])
{
	void eigsrt(float d[], float **v, int n);
	void tqli(float d[], float e[], int n, float **z);
	int i,j;
	float **z;

	z=matrix(1,n,1,n);
	for (i=1;i<=n;i++) {
		if (i != 1) b[i]=sqrt(b[i]);
		for (j=1;j<=n;j++) z[i][j]=(float)(i == j);
	}
	tqli(a,b,n,z);
	eigsrt(a,z,n);
	for (i=1;i<=n;i++) {
		x[i]=a[i];
		w[i]=amu0*z[1][i]*z[1][i];
	}
	free_matrix(z,1,n,1,n);
}
C_toolbox_eigen_sym::C_toolbox_eigen_sym(const double* dd, int dim_dd, const double* ee/*, int dim_ee, bool yesvec*/):C_toolbox()
{
    n = dim_dd;
    d = new double[n];
    for(int i=0 ; i<n ; i++) d[i] = dd[i];
    e = new double[n];
    for(int i=0 ; i<n ; i++) e[i] = ee[i];
    z = new double*[n];
    for(int i=0; i<n ; i++)
    {
        z[i] = new double[n];
        for(int j=0 ; j<n ; j++){
            if(i!=j)
                z[i][j] = 0;
            else
                z[i][i]=1.0;
        }

    }
    tqli();
    sortEig();
}
Example #16
0
int main( )
{
 float  d[5];
 float  e[5];
 float z0[5] = {1,0,0,0,0};
 float z1[5] = {0,1,0,0,0};
 float z2[5] = {0,0,1,0,0};
 float z3[5] = {0,0,0,1,0};
 float z4[5] = {0,0,0,0,1};
 float* z[5] = { z0,z1,z2,z3,z4 };
 
 d[1]=1; d[2]=2; d[3]=3; d[4]=4;
 e[1]=1; e[2]=2; e[3]=3; e[4]=4;

 printf( "Diagonais\n%d= %f %f %f %f\n%d= %f %f %f %f\n\n",
  d,d[1],d[2],d[3],d[4],
  e,e[1],e[2],e[3],e[4] );
 printf("Output[%d]\n%d= %f %f %f %f\n%d= %f %f %f %f\n%d= %f %f %f %f\n%d= %f %f %f %f\n",
  z,
  z[1],z[1][1],z[1][2],z[1][3],z[1][4],
  z[2],z[2][1],z[2][2],z[2][3],z[2][4],
  z[3],z[3][1],z[3][2],z[3][3],z[3][4],
  z[4],z[4][1],z[4][2],z[4][3],z[4][4]);
  
 tqli(d,e,4,z);
 
 printf( "Diagonais\n%d= %f %f %f %f\n[%d] \n%.50f\n %f \n%.50f\n %f\n\n",
  d,d[1],d[2],d[3],d[4],
  e,e[1],e[2],e[3],e[4] );
 printf("Output[%d]\n%d= %f %f %f %f\n%d= %f %f %f %f\n%d= %f %f %f %f\n%d= %f %f %f %f\n",
  z,
  z[1],z[1][1],z[1][2],z[1][3],z[1][4],
  z[2],z[2][1],z[2][2],z[2][3],z[2][4],
  z[3],z[3][1],z[3][2],z[3][3],z[3][4],
  z[4],z[4][1],z[4][2],z[4][3],z[4][4]);
 
 return 0;
}
Example #17
0
int eigen_sym(DMat20 H_mat, DVec20 Pi_vec, int num_state, 
	DVec20 eval, DMat20 evec, DMat20 inv_evec) {

	DVec20 forg, new_forg, forg_sqrt, off_diag, eval_new;
	DMat20 b;
	int i, j, k, error, new_num, inew, jnew;
	double zero;
	double **a;

	a = (double **) malloc(num_state * sizeof(double*));
	for (i = 0; i < num_state; i++)
		a[i] = (double*) (calloc(num_state, sizeof(double)));

	/* copy a to b */
	for (i = 0; i < num_state; i++)
		for (j = 0; j < num_state; j++) {
			a[i][j] = H_mat[i][j] / Pi_vec[i];
			b[i][j] = a[i][j];
		}
	for (i = 0; i < num_state; i++) forg[i] = Pi_vec[i];

	eliminateZero(b, forg, num_state, a, new_forg, &new_num);

	transformHMatrix(a, new_forg, forg_sqrt, new_num); 

	/* make this matrix tridiagonal */
	tred2(a, new_num, eval_new, off_diag);
	/* compute eigenvalues and eigenvectors */
	tqli(eval_new, off_diag, new_num, a);

	/* now get back eigen */
	for (i = num_state-1,inew = new_num-1; i >= 0; i--)
		eval[i] = (forg[i] > ZERO) ? eval_new[inew--] : 0;

	/* calculate the actual eigenvectors of H and its inverse matrix */
	for (i = num_state-1,inew = new_num-1; i >= 0; i--)
		if (forg[i] > ZERO) {
			for (j = num_state-1, jnew = new_num-1; j >= 0; j--) 
				if (forg[j] > ZERO) {
					evec[i][j] = a[inew][jnew] / forg_sqrt[inew];
					inv_evec[i][j] = a[jnew][inew] * forg_sqrt[jnew];
					jnew--;
				} else {
					evec[i][j] = (i == j);
					inv_evec[i][j] = (i == j);
				}
 			inew--;
		} else 
		for (j=0; j < num_state; j++) {
			evec[i][j] = (i==j);
			inv_evec[i][j] = (i==j);
		}
/*
	printf("eigen_sym \n");
	for (i = 0; i < num_state; i++)
		printf("%f ", eval[i]);
	printf("\n");*/


	/* check eigenvalue equation */
	error = 0;
	for (j = 0; j < num_state; j++) {
		for (i = 0, zero = 0.0; i < num_state; i++) {
			for (k = 0; k < num_state; k++) zero += b[i][k] * evec[k][j];
			zero -= eval[j] * evec[i][j];
			if (fabs(zero) > 1.0e-5) {
				error = 1;
				printf("zero = %f\n", zero);
			}
		}

		for (i = 0, zero = 0.0; i < num_state; i++) {
			for (k = 0; k < num_state; k++) zero += evec[i][k] * inv_evec[k][j];
			if (i == j) zero -= 1.0;
			if (fabs(zero) > 1.0e-5) {
				error = 1;
				printf("zero = %f\n", zero);
			}
		}

	}

	for (i = num_state-1; i >= 0; i--)
		free(a[i]);
	free(a);

	if (error) {
		printf("\nWARNING: Eigensystem doesn't satisfy eigenvalue equation!\n");
		return 1;
	}

	return 0;
}
Example #18
0
bool Plane::FitToPoints(const Vector<Vec4f> &Points, Vec3f &Basis1, Vec3f &Basis2, float &NormalEigenvalue, float &ResidualError)
{
    Vec3f Centroid, Normal;

    float ScatterMatrix[3][3];
    int  Order[3];
    float DiagonalMatrix[3];
    float OffDiagonalMatrix[3];

    // Find centroid
    Centroid = Vec3f::Origin;
    float TotalWeight = 0.0f;
    for(UINT i = 0; i < Points.Length(); i++)
    {
        TotalWeight += Points[i].w;
        Centroid += Vec3f(Points[i].x, Points[i].y, Points[i].z) * Points[i].w;
    }
    Centroid /= TotalWeight;

    // Compute scatter matrix
    Find_ScatterMatrix(Points, Centroid, ScatterMatrix, Order);

    tred2(ScatterMatrix,DiagonalMatrix,OffDiagonalMatrix);
    tqli(DiagonalMatrix,OffDiagonalMatrix,ScatterMatrix);

    /*
    **    Find the smallest eigenvalue first.
    */
    float Min = DiagonalMatrix[0];
    float Max = DiagonalMatrix[0];
    UINT MinIndex = 0;
    UINT MiddleIndex = 0;
    UINT MaxIndex = 0;
    for(UINT i = 1; i < 3; i++)
    {
        if(DiagonalMatrix[i] < Min)
        {
            Min = DiagonalMatrix[i];
            MinIndex = i;
        }
        if(DiagonalMatrix[i] > Max)
        {
            Max = DiagonalMatrix[i];
            MaxIndex = i;
        }
    }
    for(UINT i = 0; i < 3; i++)
    {
        if(MinIndex != i && MaxIndex != i)
        {
            MiddleIndex = i;
        }
    }
    /*
    **    The normal of the plane is the smallest eigenvector.
    */
    for(UINT i = 0; i < 3; i++)
    {
        Normal[Order[i]] = ScatterMatrix[i][MinIndex];
        Basis1[Order[i]] = ScatterMatrix[i][MiddleIndex];
        Basis2[Order[i]] = ScatterMatrix[i][MaxIndex];
    }
    NormalEigenvalue = Math::Abs(DiagonalMatrix[MinIndex]);
    Basis1.SetLength(DiagonalMatrix[MiddleIndex]);
    Basis2.SetLength(DiagonalMatrix[MaxIndex]);

    if(!Basis1.Valid() || !Basis2.Valid() || !Normal.Valid())
    {
        *this = ConstructFromPointNormal(Centroid, Vec3f::eX);
        Basis1 = Vec3f::eY;
        Basis2 = Vec3f::eZ;
    }
    else
    {
        *this = ConstructFromPointNormal(Centroid, Normal);
    }

    ResidualError = 0.0f;
    for(UINT i = 0; i < Points.Length(); i++)
    {
        ResidualError += UnsignedDistance(Vec3f(Points[i].x, Points[i].y, Points[i].z));
    }
    ResidualError /= Points.Length();

    return true;
}
Example #19
0
bool ClipPlane::fitPointsToPlane( const std::vector<cc::Vec4f>& points, cc::Vec3f& basis1, cc::Vec3f& basis2, float& normalEigenValue, float& residualError, ClipPlane& outPlane ) {
	// find centroid
	cc::Vec3f centroid(0.0f, 0.0f, 0.0f);
	float totalWeight = 0.0f;
	for( const auto& p : points ) {
		totalWeight += p.w;
		centroid += cc::Vec3f(p.x, p.y, p.z) * p.w;
	}
	centroid /= totalWeight;

	// compute scatter matrix
	float scatterMatrix[3][3];
	int order[3];
	findScatterMatrix(points, centroid, scatterMatrix, order);

	float diagonalMatrix[3];
	float offDiagonalMatrix[3];
	tred2(scatterMatrix, diagonalMatrix, offDiagonalMatrix);
	tqli(diagonalMatrix, offDiagonalMatrix, scatterMatrix);

	// find smallest eigenvalue first
	float min = diagonalMatrix[0];
	float max = diagonalMatrix[0];
	unsigned int minIndex = 0;
	unsigned int middleIndex = 0;
	unsigned int maxIndex = 0;
	for( unsigned int i = 1; i < 3; i++ ) {
		if( diagonalMatrix[i] < min ) {
			min = diagonalMatrix[i];
			minIndex = i;
		}
		if( diagonalMatrix[i] > max ) {
			max = diagonalMatrix[i];
			maxIndex = i;
		}
	}
	for( unsigned int i = 0; i < 3; i++ ) {
		if( minIndex != i && maxIndex != i ) {
			middleIndex = i;
		}
	}

	// the normal of the plane is the smallest eigenvector.
	cc::Vec3f normal;
	for( unsigned int i = 0; i < 3; i++ ) {
		normal[order[i]] = scatterMatrix[i][minIndex];
		basis1[order[i]] = scatterMatrix[i][middleIndex];
		basis2[order[i]] = scatterMatrix[i][maxIndex];
	}
	normalEigenValue = fabsf(diagonalMatrix[minIndex]);
	setVec3Length(basis1, diagonalMatrix[middleIndex]);
	setVec3Length(basis2, diagonalMatrix[maxIndex]);

	if( !isVec3Valid(basis1) || !isVec3Valid(basis2) || !isVec3Valid(normal) ) {
		outPlane = ClipPlane::constructFromPointNormal(centroid, cc::Vec3f(1.0f, 0.0f, 0.0f));
		basis1 = cc::Vec3f(0.0f, 1.0f, 0.0f);
		basis2 = cc::Vec3f(0.0f, 0.0f, 1.0f);
	} else {
		outPlane = ClipPlane::constructFromPointNormal(centroid, normal);
	}

	residualError = 0.0f;
	for( unsigned int i = 0; i < points.size(); i++ ) {
		residualError += outPlane.unsignedDistance(cc::Vec3f(points[i].x, points[i].y, points[i].z));
	}
	residualError /= points.size();

	return true;
}
Example #20
0
File: pca.c Project: c4dm/qm-dsp
/* In place projection onto basis vectors */
void pca_project(double** data, int n, int m, int ncomponents)
{
	int  i, j, k, k2;
	double  **symmat, /* **symmat2, */ *evals, *interm;
	
	//TODO: assert ncomponents < m
	
	symmat = (double**) malloc(m*sizeof(double*));
	for (i = 0; i < m; i++)
		symmat[i] = (double*) malloc(m*sizeof(double));
		
	covcol(data, n, m, symmat);
	
	/*********************************************************************
		Eigen-reduction
		**********************************************************************/
	
    /* Allocate storage for dummy and new vectors. */
    evals = (double*) malloc(m*sizeof(double));     /* Storage alloc. for vector of eigenvalues */
    interm = (double*) malloc(m*sizeof(double));    /* Storage alloc. for 'intermediate' vector */
    //MALLOC_ARRAY(symmat2,m,m,double);    
	//for (i = 0; i < m; i++) {
	//	for (j = 0; j < m; j++) {
	//		symmat2[i][j] = symmat[i][j]; /* Needed below for col. projections */
	//	}
	//}
    tred2(symmat, m, evals, interm);  /* Triangular decomposition */
tqli(evals, interm, m, symmat);   /* Reduction of sym. trid. matrix */
/* evals now contains the eigenvalues,
columns of symmat now contain the associated eigenvectors. */	

/*
	printf("\nEigenvalues:\n");
	for (j = m-1; j >= 0; j--) {
		printf("%18.5f\n", evals[j]); }
	printf("\n(Eigenvalues should be strictly positive; limited\n");
	printf("precision machine arithmetic may affect this.\n");
	printf("Eigenvalues are often expressed as cumulative\n");
	printf("percentages, representing the 'percentage variance\n");
	printf("explained' by the associated axis or principal component.)\n");
	
	printf("\nEigenvectors:\n");
	printf("(First three; their definition in terms of original vbes.)\n");
	for (j = 0; j < m; j++) {
		for (i = 1; i <= 3; i++)  {
			printf("%12.4f", symmat[j][m-i]);  }
		printf("\n");  }
 */

/* Form projections of row-points on prin. components. */
/* Store in 'data', overwriting original data. */
for (i = 0; i < n; i++) {
	for (j = 0; j < m; j++) {
		interm[j] = data[i][j]; }   /* data[i][j] will be overwritten */
        for (k = 0; k < ncomponents; k++) {
			data[i][k] = 0.0;
			for (k2 = 0; k2 < m; k2++) {
				data[i][k] += interm[k2] * symmat[k2][m-k-1]; }
        }
}

/*	
printf("\nProjections of row-points on first 3 prin. comps.:\n");
 for (i = 0; i < n; i++) {
	 for (j = 0; j < 3; j++)  {
		 printf("%12.4f", data[i][j]);  }
	 printf("\n");  }
 */

/* Form projections of col.-points on first three prin. components. */
/* Store in 'symmat2', overwriting what was stored in this. */
//for (j = 0; j < m; j++) {
//	 for (k = 0; k < m; k++) {
//		 interm[k] = symmat2[j][k]; }  /*symmat2[j][k] will be overwritten*/
//  for (i = 0; i < 3; i++) {
//	symmat2[j][i] = 0.0;
//		for (k2 = 0; k2 < m; k2++) {
//			symmat2[j][i] += interm[k2] * symmat[k2][m-i-1]; }
//		if (evals[m-i-1] > 0.0005)   /* Guard against zero eigenvalue */
//			symmat2[j][i] /= sqrt(evals[m-i-1]);   /* Rescale */
//		else
//			symmat2[j][i] = 0.0;    /* Standard kludge */
//    }
// }

/*
 printf("\nProjections of column-points on first 3 prin. comps.:\n");
 for (j = 0; j < m; j++) {
	 for (k = 0; k < 3; k++)  {
		 printf("%12.4f", symmat2[j][k]);  }
	 printf("\n");  }
	*/


for (i = 0; i < m; i++)
	free(symmat[i]);
free(symmat);
//FREE_ARRAY(symmat2,m);
free(evals);
free(interm);

}
Example #21
0
gint cmds (array_d *D, array_d *X)
{
  gint N = D->nrows;
    /*  D_ij^2 = ||X_i  - x_j||^2  */ 
  gdouble C = 0;    /*  C = 2/N sum_ij (D_ij^2)    */
  array_d c;
  gint i, j, ncols;
  gdouble sum;
    /*  c_ij = <x_i, x_j>      */
  gdouble *d = g_malloc (N * sizeof (gdouble));
  gdouble *e = g_malloc (N * sizeof (gdouble));

  arrayd_init_null (&c);
  arrayd_alloc (&c, N, N);
  
  /* diagonal and off-diagonal elements of tridiagonalisation of c (e[0]=0) */

/* compute constant C */
  for (i = 0; i < N; i++) {
    for (j = 0; j < N; j++)
      C += sqr(D->vals[i][j]);
  }
  C /= (gdouble) (N*N);

/*  recover scalar products from distances */
  /*  diagonal elements */
  for (i = 0; i < N; i++) {
    sum = 0;
    for (j = 0; j < N; j++) 
      sum += sqr(D->vals[i][j]);
    
    c.vals[i][i] = sum/N - .5*C;
  }

  /*  upper triangle */
  for (i = 0; i < N; i++) {
    for (j = i+1; j < N; j++) {
      c.vals[j][i] = c.vals[i][j] =
        -.5*(sqr(D->vals[i][j]) - c.vals[i][i] - c.vals[j][j]);
    }
  }

/*
  printf("matrix of scalar products:");
  printX(c,N,1);
  printf("\ntrace of c: %.2f\n",tr(c,N));
*/


/*  calculate eigenvectors and eigenvalues */

  /*  tridiagonalize c into d (diagonal) and e (off-diagonal) */
  tred2(c.vals,N,d,e);  
g_printerr ("through tred2\n");

/*
  printf("diagonal:\n"); 
  for (i = 0; i < N; i++) { printf("%.2f ",d[i]); }
  printf("\noff-diagonal:"); 
  for (i = 1; i < N; i++) { printf("%.2f ",e[i]); }
  printf("\n"); 
*/

  /* 
   * Tridiagonal QL Implicit: calculate eigenvectors and -values from
   * a tridiagonal matrix
  */
  tqli (d, e, N, c.vals);
g_printerr ("through tqli\n");
  eigensort (c.vals, d, N);
g_printerr ("through eigensort\n");

  sum = 0;
  for (i = 0; i < N; i++) {
    sum += d[i];
  }
g_printerr ("trace of c after decomposition: %.2f\n",sum); 

/*
  printf("\nX:\n"); 
  recoverX (c.vals, d, N);
  printX(c,N,1);
*/
  ncols = MIN (N, X->ncols);
  for (i = 0; i < N; i++) {
    for (j = 0; j < ncols; j++) {
      if (d[j] > 0) 
        X->vals[i][j] = c.vals[i][j] * sqrt(d[j]);
      else X->vals[i][j] = 0;
    }
  }

  arrayd_free (&c, 0, 0);
  g_free (d);
  g_free (e);

  return 0;
}
Example #22
0
void diagonalize( Matrix& mat, Matrix& eigen, Vector& eval) {

    if (mat.size1() == 0 || mat.size2() == 0) return;

    int size = mat.size1();
    if ( size != mat.size2() ) {
        cerr << " diagonalize() : Matrix mat must be quadratic.\n";
        abort();
    }
    if ( eigen.size1() != size ) {
        cerr << " diagonalize() : Matries mat and eigen do not match.\n";
        abort();
    }
    if ( eigen.size2() != size ) {
        cerr << " diagonalize() : Matries mat and eigen do not match.\n";
        abort();
    }
    if ( eval.size() != size ) {
        cerr << " diagonalize() : Matries mat and eval do not match.\n";
        abort();
    }

    int i, j, k;

#ifdef SUN_IMSL

    // extract pointers to data fields:

    double* matptr = &mat(0,0);
    double* eigptr = &eigen(0,0);
    double*  evptr = &eval[0];

    devcsf_( &size, matptr, &size, evptr, eigptr, &size);

    //  Normalize the eigenvectors

    double norm;
    for( i=0; i<size; i++) {
        norm = 0;
        for( j=0; j<size; j++ )
            norm += eigen(i,j)*eigen(i,j);
        norm = 1 / sqrt(norm);
        for( j=0; j<size; j++)
            eigen(i,j) *= norm;
    }

    return;

#else

    eigen = mat;

    Vector tmp( size );
    Matrix orig( size, size );
    orig = mat;
    tred2old( eigen, eval, tmp );
    tqli( eval, tmp, eigen );

    straightsort( eval, eigen );

    //  Check the eigensolutions

    double s;
    for(i=0; i<size; i++) {
        for(j=0; j<size; j++) {

            s = 0.0;
            for(k=0; k<size; k++)
                s += orig(j,k) * eigen(k,i);
            if (fabs(s - eval[i]*eigen(j,i)) > 1E-7)
                cout << " diag() error 2 : " << i <<" "<< j << " : " <<
                     s - eval[i]*eigen(j,i) <<"\n";

        }
    }

    return;

#endif

}
Example #23
0
int main(int argc, const char * argv[]) {
    
    std::cout.precision(dbl::max_digits10);
    
    unsigned int N      = 200;                           // The Matrix Size.  Nstep = N + 1.  Npoints = N + 2.
    double       rhoMin = 0.0;                          // The starting position.
    double       rhoMax = 4.0;
    double       h      = (rhoMax - rhoMin) / (N + 1);  // The step length
    double       h2     = h*h;                          // Step Length Squared;

    clock_t begin_time;             // Variable for keeping track of computation times.


    // Code for part B
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    

    // Implement the Jacobi Method
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    if (false) {
        std::cout << " ----------- Jacobi Method ----------- " << std::endl;

        unsigned int maxRecursion = 1000000;          // Maximum number of times "for" loop will run.
        double       tolerance    = 0.1;            // When all off diagonal matrix elements are < this, the matrix is
                                                    // considered diagonalized.

        // Generate the A matrix which the Jacobi Method will diagonalize
        double* a = function::generateConstantVector(N-1, -1.0/h2);
        double* c = function::generateConstantVector(N-1, -1.0/h2);
        
        double* b = new double [N];
        for (int i = 0; i < N; i++) {
            b[i] = (2.0 / h2) + V(rhoMin + (i+1)*h);
        }

        // Passing vector arguments instead of making calls to the functions
        // that generate the vector arguments allows the following function
        // to be vectorizable.
        double** A = function::genTridiagMatVectArgsExact(N, a, b, c);

        delete [] a;
        delete [] b;
        delete [] c;

        // Variables for Jacobi's Metod "for" loop
        double theta;
        unsigned int x;
        unsigned int y;
        unsigned int* p = &x;
        unsigned int* q = &y;
        double z;
        double* maxValue = &z;
        unsigned int numberOfItterations = 0;
        
        begin_time = clock();                       // Start the clock.
        
        function::maxOffDiagnalElement(A, N, maxValue, p, q);
        for (unsigned int* i = &numberOfItterations; (*i < maxRecursion) && (*maxValue > tolerance); *i += 1) {
            function::maxOffDiagnalElement(A, N, maxValue, p, q);
            theta = atan(
                         (2.0 * A[*p][*q]) / (A[*q][*q] - A[*p][*p])
                         ) / 2.0;
            
            // Unit Test
            if (fabs(theta) > M_PI_4) {
                std::cout << "!! -- Jacobi Method Error: theta outside expected range -- !!" << std::endl;
            }
            
            function::jacobiRotation(A, N, *p, *q, theta);
        }
        
        std::cout << "Total computation time [s] = " << float( clock () - begin_time ) /  CLOCKS_PER_SEC << std::endl;
        std::cout << "Number of itterations performed = " << numberOfItterations << std::endl;
        std::cout << "Lagrest Off Diagonal Element = " << *maxValue << std::endl;
        std::cout << "Smallest eigenvalue = " << function::threeMinDiagonalElements(A, N)[0] << std::endl;
        std::cout << "2nd Smallest eigenvalue = " << function::threeMinDiagonalElements(A, N)[1] << std::endl;
        std::cout << "3rd Smallest eigenvalue = " << function::threeMinDiagonalElements(A, N)[2] << std::endl;

        // Deallocate memory for "A" matrix.
        for (unsigned int i = 0; i<N; i++) {
            delete [] A[i];
        }
        delete [] A;

    }


    // Implement Householder Algorithm
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    if (false) {
        std::cout << " ----------- Householder Algorithm ----------- " << std::endl;

        //make identity matrix for tqli
        double* ones  = function::generateConstantVector(N, 1);
        double* zeros = function::generateConstantVector(N-1, 0);
        double** I    = function::genTridiagMatVectArgsExact(N, zeros, ones, zeros);

        // "ones" and "zeros" no longer needed.
        delete [] ones;
        delete [] zeros;

        double* a = function::generateConstantVector(N-1, -1.0/h2);

        double* b = new double [N];
        for (int i = 0; i < N; i++) {
            b[i] = (2.0 / h2) + V(rhoMin + (i+1)*h);
        }

        begin_time = clock();                                   // Start the clock.
        
        tqli(b,a,N,I); // householder method
        
        std::cout << "Total computation time [s] = "                 << float( clock () - begin_time ) /  CLOCKS_PER_SEC << std::endl;
        std::cout << "Smallest eigenvalue (should be 3) = \t\t"      << function::minVectorElements(b, N, 3)[0]          << std::endl;
        std::cout << "Second smallest eigenvalue (should be 7) = \t" << function::minVectorElements(b, N, 3)[1]          << std::endl;
        std::cout << "Third smallest eigenvalue (should be 11) = \t" << function::minVectorElements(b, N, 3)[2]          << std::endl;

        // Save output
        if (true) {
            function::saveMatrix4Mathematica("/Volumes/userFilesPartition/Users/curtisrau/Documents/School/Physics/PHY480ComputationalPhysics/Project2/project2-repository/dataOut/solutionMatrix.csv", I, N, N);
            function::saveArray4Mathematica("/Volumes/userFilesPartition/Users/curtisrau/Documents/School/Physics/PHY480ComputationalPhysics/Project2/project2-repository/dataOut/eigenvalueArray.csv", b, N);
        }

        // Deallocate Memory
        delete [] a;    // "a" no longer needed.
        delete [] b;
        for (unsigned int i = 0; i<N; i++) {
            delete [] I[i];
        }
        delete [] I;

    }
    
//=======
//    double* a = function::generateConstantVector(N-1, -1/h2);
//    double* c = function::generateConstantVector(N-1, -1/h2);
//    double* b = new double[N];
//    b[0]=2/h2;
//    for (int i = 1; i < N; i++) {
//        b[i] = 2/h2 + V(i*h);
//    }
//    function::printVector(b,N);
//    // Passing vector arguments instead of making calls to the functions
//    // that generate the vector arguments allows the following function
//    // to be vectorizable.
//    double** A = function::genTridiagMatVectArgsExact(N, a, b, c);
//    
//    //delete [] a;
//    //delete [] b;
//    delete [] c;
//>>>>>>> Ben
    
    // Code for part C
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    if (false) {
        std::cout << "-- Begin Part C --" << std::endl;
        
        double* omega = new double [4];
        omega[0] = 1.0 / 4.0;
        omega[1] = 0.5;
        omega[2] = 1;
        omega[3] = 5;
////=======
//    unsigned int x;
//    unsigned int y;
//    unsigned int* p = &x;
//    unsigned int* q = &y;
//    double theta = 100;
//    unsigned int maxRecursion = 100;        // Maximum number of times for loop will run.
//    double minTheta = .000000000000000000000000000000000000000001;
//
//    for (unsigned int i = 0; theta > minTheta; i++) {
//        function::maxOffDiagnalElement(A, N, N, p, q);
//        theta = atan(
//                     (2*A[*p][*q]) / (A[*q][*q] - A[*p][*p])
//                     ) / 2.0;
//        function::jacobiRotation(A, N, *p, *q, theta);
//        std::cout << theta << endl;
//        //function::printMatrix(A, N, N);
//    }
////>>>>>>> Ben

    for (int r = 0; r < 4; r++) {
    std::cout << "-----------------\nOmega = " << omega[r] << std::endl;

        // Implement the Jacobi Method
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        if (true) {
            std::cout << " ----------- Jacobi Method ----------- " << std::endl;

            unsigned int maxRecursion = 50000;          // Maximum number of times "for" loop will run.
            double       tolerance    = 0.1;         // When all off diagonal matrix elements are < this, the matrix is
                                                        // considered diagonalized.

            begin_time = clock();                       // Start the clock.

            // Generate the A matrix which the Jacobi Method will diagonalize
            double* a = function::generateConstantVector(N-1, -1.0/h2);
            double* c = function::generateConstantVector(N-1, -1.0/h2);

            double* b = new double [N];
            for (int i = 0; i < N; i++) {
                b[i] = (2.0 / h2) + Vc(rhoMin + (i+1)*h,omega[r]);
            }

            // Passing vector arguments instead of making calls to the functions
            // that generate the vector arguments allows the following function
            // to be vectorizable.
            double** A = function::genTridiagMatVectArgsExact(N, a, b, c);

            delete [] a;
            delete [] b;
            delete [] c;

            // Variables for Jacobi's Metod "for" loop
            double theta;
            unsigned int x;
            unsigned int y;
            unsigned int* p = &x;
            unsigned int* q = &y;
            double z;
            double* maxValue = &z;
            unsigned int numberOfItterations = 0;

            function::maxOffDiagnalElement(A, N, maxValue, p, q);
            for (unsigned int* i = &numberOfItterations; (*i < maxRecursion) && (*maxValue > tolerance); *i += 1) {
                function::maxOffDiagnalElement(A, N, maxValue, p, q);
                theta = atan(
                             (2.0 * A[*p][*q]) / (A[*q][*q] - A[*p][*p])
                             ) / 2.0;
                
                // Unit Test
                if (fabs(theta) > M_PI_4) {
                    std::cout << "!! -- Jacobi Method Error: theta outside expected range -- !!" << std::endl;
                }
                
                function::jacobiRotation(A, N, *p, *q, theta);
            }

            std::cout << "Total computation time [s] = " << float( clock () - begin_time ) /  CLOCKS_PER_SEC << std::endl;
            std::cout << "Number of itterations performed = " << numberOfItterations << std::endl;
            std::cout << "Lagrest Off Diagonal Element = " << *maxValue << std::endl;
            std::cout << "Smallest eigenvalue = " << function::threeMinDiagonalElements(A, N)[0] << std::endl;
            std::cout << "2nd Smallest eigenvalue = " << function::threeMinDiagonalElements(A, N)[1] << std::endl;
            std::cout << "3rd Smallest eigenvalue = " << function::threeMinDiagonalElements(A, N)[2] << std::endl;

            // Deallocate memory for "A" matrix.
            for (unsigned int i = 0; i < N; i++) {
                delete [] A[i];
            }
            delete [] A;

        }
    }
    
    }
    
    
    // Code for part D
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    if (true) {
        std::cout << "-- Begin Part D --" << std::endl;
        
        double omega = 0.00095;
        
        begin_time = clock();                                   // Start the clock.
        
        //make identity matrix for tqli
        double* ones  = function::generateConstantVector(N, 1);
        double* zeros = function::generateConstantVector(N-1, 0);
        double** I    = function::genTridiagMatVectArgsExact(N, zeros, ones, zeros);
        
        // "ones" and "zeros" no longer needed.
        delete [] ones;
        delete [] zeros;
        
        double* a = function::generateConstantVector(N-1, -1.0/h2);
        
        double* b = new double [N];
        for (int i = 0; i < N; i++) {
            b[i] = (2.0 / h2) + Vc(rhoMin + static_cast<double>(i+1)*h, omega);
        }
        
        tqli(b,a,N,I); // householder method
        
        delete [] a;    // "a" no longer needed.
        
        // This transforms our solution into the "true" solution (better explanation?)
        function::transposeMatrix(I, N);
        function::reorderSolution(I, b, N);
        for (unsigned int i = 0; i < N; i++) {
            function::deradializeSolution(I[i], N, rhoMin + h, h);
            function::squareVector(I[i], N);
            function::vectorNormalize(I[i], N, h);
        }
//
//        
//        std::cout << "Total computation time [s] = " << float( clock () - begin_time ) /  CLOCKS_PER_SEC << std::endl;
//        std::cout << "Smallest eigenvalue        = " << function::minVectorElements(b, N, 3)[0]          << std::endl;
//        std::cout << "Second smallest eigenvalue = " << function::minVectorElements(b, N, 3)[1]          << std::endl;
//        std::cout << "Third smallest eigenvalue  = " << function::minVectorElements(b, N, 3)[2]          << std::endl;
        
        // Save output
        if (true) {
            function::saveMatrix4Mathematica("/Volumes/userFilesPartition/Users/curtisrau/Documents/School/Physics/PHY480ComputationalPhysics/Project2/project2-repository/dataOut/solutionMatrix.csv", I, N, N);
            function::saveArray4Mathematica("/Volumes/userFilesPartition/Users/curtisrau/Documents/School/Physics/PHY480ComputationalPhysics/Project2/project2-repository/dataOut/eigenvalueArray.csv", b, N);
        }
        
//        // Deallocate Memory
//        delete [] b;
//        for (unsigned int i = 0; i<N; i++) {
//            delete [] I[i];
//        }
//        delete [] I;
    }

    return 0;
}