Example #1
0
void EigenProblemsTest::testGeev1()
{
  std::cout << "--> Test: geev1." <<std::endl;
  // Compute only right eigenvectors.
  complex_matrix fake(1,1), rightV(size,size);
  complex_vector eigenval(size);
  Siconos::eigenproblems::geev(*A, eigenval, fake, rightV);
  complex_vector error(size);
  for( unsigned int i = 0; i < size; ++i ) error(i) = 0.0;
  for( unsigned int i = 0; i < size; ++i )
  {
    error.plus_assign(ublas::prod(*A->dense(), column(rightV, i) ));
    error.minus_assign(eigenval(i)*column(rightV,i));
  }

  // Check ...
  CPPUNIT_ASSERT_EQUAL_MESSAGE("testGeev1 1: ", norm_2(error) < 10 * std::numeric_limits< double >::epsilon() , true);
  // Check if A has not been modified
  CPPUNIT_ASSERT_EQUAL_MESSAGE("testGeev1 2: ", (*A) == (*Aref) , true);
  // Now compute only eigenvalues 
  complex_vector RefEigenValues(size);
  RefEigenValues = eigenval;
  eigenval *= 0.0;
  Siconos::eigenproblems::geev(*A, eigenval, fake, fake, false, false);
  
  CPPUNIT_ASSERT_EQUAL_MESSAGE("testGeev1 3: ", norm_2(eigenval - RefEigenValues) < 10 * std::numeric_limits< double >::epsilon() , true);
  CPPUNIT_ASSERT_EQUAL_MESSAGE("testGeev1 4: ", (*A) == (*Aref) , true);

  std::cout << "--> geev1 test ended with success." <<std::endl;
}
Example #2
0
void EigenProblemsTest::testGeev3()
{
  std::cout << "--> Test: geev3." <<std::endl;

  // Compute left and right eigenvectors.
  complex_matrix leftV(size,size), rightV(size,size);
  complex_vector eigenval(size);
  Siconos::eigenproblems::geev(*A, eigenval, leftV, rightV, true, true);
  complex_vector error(size);
  for( unsigned int i = 0; i < size; ++i ) error(i) = 0.0;
  for( unsigned int i = 0; i < size; ++i )
  {
    error.plus_assign(ublas::prod(*A->dense(), column(rightV, i) ));
    error.minus_assign(eigenval(i)*column(rightV,i));
    error.plus_assign(ublas::prod(conj(column(leftV, i)), *A->dense() ));
    error.minus_assign(eigenval(i)*conj(column(leftV,i)));
  }
  std::cout << norm_2(error) << std::endl;
  // Check ...
  CPPUNIT_ASSERT_EQUAL_MESSAGE("testGeev3 1: ", norm_2(error) < size * 10 * std::numeric_limits< double >::epsilon() , true);
  // Check if A has not been modified
  CPPUNIT_ASSERT_EQUAL_MESSAGE("testGeev3 2: ", (*A) == (*Aref) , true);

  std::cout << "--> geev3 test ended with success." <<std::endl;
}
//------------------------------------------------------------------------------
void MfLowRankApproximation::integrate(const int q, const int r, const cx_mat &C, cx_vec &V2)
{
    Vm.zeros();
    V2.zeros();

    for(int m=0; m<M; m++) {
        for(int j=0; j<nGrid; j++) {
            Vm(m) += std::conj(C(j,q))*U(j,m)*C(j,r);
        }
    }

    for(int i=0; i<nGrid; i++) {
        for(int m=0; m<M; m++) {
            V2(i) += eigenval(m)*U(i,m)*Vm(m);
        }
    }
}
Example #4
0
// eigen-decomposition of a symmetric matrix
void Matrix::eig(Matrix& U, Matrix& lambda, unsigned int iter, bool ignoreError) const
{
	ASSERT(isValid() && isSquare());
	Matrix basic = *this;
	Matrix eigenval(m_rows);

	// 1-dim case
	if (m_rows == 1) { basic(0, 0) = 1.0; eigenval(0) = m_data[0]; return; }

	std::vector<double> oD(m_rows);
	unsigned int i, j, k, l, m;
	double b, c, f, g, h, hh, p, r, s, scale;

	// reduction to tridiagonal form
	for (i=m_rows; i-- > 1;)
	{
		h = 0.0;
		scale = 0.0;
		if (i > 1) for (k = 0; k < i; k++) scale += fabs(basic(i, k));

		if (scale == 0.0) oD[i] = basic(i, i-1);
		else
		{
			for (k = 0; k < i; k++)
			{
				basic(i, k) /= scale;
				h += basic(i, k) * basic(i, k);
			}

			f = basic(i, i-1);
			g = (f > 0.0) ? -::sqrt(h) : ::sqrt(h);
			oD[i] = scale * g;
			h -= f * g;
			basic(i, i-1) = f - g;
			f = 0.0;

			for (j = 0; j < i; j++)
			{
				basic(j, i) = basic(i, j) / (scale * h);
				g = 0.0;
				for (k=0; k <= j; k++) g += basic(j, k) * basic(i, k);
				for (k=j+1; k < i; k++) g += basic(k, j) * basic(i, k);
				f += (oD[j] = g / h) * basic(i, j);
			}
			hh = f / (2.0 * h);

			for (j=0; j < i; j++)
			{
				f = basic(i, j);
				g = oD[j] - hh * f;
				oD[j] = g;
				for (k=0; k <= j; k++) basic(j, k) -= f * oD[k] + g * basic(i, k);
			}

			for (k=i; k--;) basic(i, k) *= scale;
		}
		eigenval(i) = h;
	}
	eigenval(0) = oD[0] = 0.0;

	// accumulation of transformation matrices
	for (i=0; i < m_rows; i++)
	{
		if (eigenval(i) != 0.0)
		{
			for (j=0; j < i; j++)
			{
				g = 0.0;
				for (k = 0; k < i; k++) g += basic(i, k) * basic(k, j);
				for (k = 0; k < i; k++) basic(k, j) -= g * basic(k, i);
			}
		}
		eigenval(i) = basic(i, i);
		basic(i, i) = 1.0;
		for (j=0; j < i; j++) basic(i, j) = basic(j, i) = 0.0;
	}

	// eigenvalues from tridiagonal form
	for (i=1; i < m_rows; i++) oD[i-1] = oD[i];
	oD[m_rows - 1] = 0.0;

	for (l=0; l < m_rows; l++)
	{
		j = 0;
		do
		{
			// look for small sub-diagonal element
			for (m=l; m < m_rows - 1; m++)
			{
				s = fabs(eigenval(m)) + fabs(eigenval(m + 1));
				if (fabs(oD[m]) + s == s) break;
			}
			p = eigenval(l);

			if (m != l)
			{
				if (j++ == iter)
				{
					// Too many iterations --> numerical instability!
					if (ignoreError) break;
					else throw("[Matrix::eig] numerical problems");
				}

				// form shift
				g = (eigenval(l+1) - p) / (2.0 * oD[l]);
				r = ::sqrt(g * g + 1.0);
				g = eigenval(m) - p + oD[l] / (g + ((g > 0.0) ? fabs(r) : -fabs(r)));
				s = 1.0;
				c = 1.0;
				p = 0.0;

				for (i=m; i-- > l;)
				{
					f = s * oD[i];
					b = c * oD[i];
					if (fabs(f) >= fabs(g))
					{
						c = g / f;
						r = ::sqrt(c * c + 1.0);
						oD[i+1] = f * r;
						s = 1.0 / r;
						c *= s;
					}
					else
					{
						s = f / g;
						r = ::sqrt(s * s + 1.0);
						oD[i+1] = g * r;
						c = 1.0 / r;
						s *= c;
					}

					g = eigenval(i+1) - p;
					r = (eigenval(i) - g) * s + 2.0 * c * b;
					p = s * r;
					eigenval(i+1) = g + p;
					g = c * r - b;

					for (k=0; k < m_rows; k++)
					{
						f = basic(k, i+1);
						basic(k, i+1) = s * basic(k, i) + c * f;
						basic(k, i) = c * basic(k, i) - s * f;
					}
				}

				eigenval(l) -= p;
				oD[l] = g;
				oD[m] = 0.0;
			}
		}
		while (m != l);
	}

	// normalize eigenvectors
	for (j=m_rows; j--;)
	{
		s = 0.0;
		for (i=m_rows; i--;) s += basic(i, j) * basic(i, j);
		s = ::sqrt(s);
		for (i=m_rows; i--;) basic(i, j) /= s;
	}

	// sort by eigenvalues
	std::vector<unsigned int> index(m_rows);
	for (i=0; i<m_rows; i++) index[i] = i;
	CmpIndex cmpidx(eigenval, index);
	std::sort(index.begin(), index.end(), cmpidx);
	U.resize(m_rows, m_rows);
	lambda.resize(m_rows);
	for (i=0; i<m_rows; i++)
	{
		j = index[i];
		lambda(i) = eigenval(j);
		for (k=0; k<m_rows; k++) U(k, i) = basic(k, j);
	}
}
//------------------------------------------------------------------------------
void MfLowRankApproximation::initialize()
{
    double dx;
    double constValue;
    double endValue;
    double constEnd;
    double epsilon;


    dx = grid.DX;
    try {
        nOrbitals = cfg->lookup("spatialDiscretization.nSpatialOrbitals");
        constEnd = cfg->lookup("meanFieldIntegrator.lowRankApproximation.constEnd");
        constValue = cfg->lookup("meanFieldIntegrator.lowRankApproximation.constValue");
        endValue = cfg->lookup("meanFieldIntegrator.lowRankApproximation.endValue");
        epsilon = cfg->lookup("meanFieldIntegrator.lowRankApproximation.epsilon");
    } catch (const SettingNotFoundException &nfex) {
        cerr << "MfLowRankApproximation::Error reading entry from config object." << endl;
        exit(EXIT_FAILURE);
    }

    int nConst = constEnd/dx;
    int constCenter = nGrid/2;
    Vxy = zeros(nGrid, nGrid);

    for(uint p=0; p<potential.size(); p++) {
        for(int i=0; i<nGrid; i++) {
            for(int j=0; j<nGrid; j++) {
                Vxy(i, j) += potential[p]->evaluate(i, j);
            }
        }
    }

    // Using a simple discretization equal to the discretization of
    // the system.
    mat h = hExactSpatial();
//    mat h = hPiecewiseLinear();
    mat Q = eye(nGrid,nGrid);

    // Using a consant weight in the center of the potential
    // and a linear decrease from the center.
    vec g = gLinear(nGrid, constCenter, nConst, constValue, endValue);
    mat C = cMatrix(g, h, dx);

    vec lambda;
    mat eigvec;
    eig_sym(lambda, eigvec, inv(C.t())*Vxy*inv(C));
    mat Ut = C.t()*eigvec;

    mat QU = inv(Q)*Ut;

    // Sorting the eigenvalues by absoulte value and finding the number
    // of eigenvalues with abs(eigenval(i)) > epsilon
    uvec indices = sort_index(abs(lambda), 1);
    M = -1;
    for(uint m=0; m <lambda.n_rows; m++) {
        cout << abs(lambda(indices(m))) << endl;
        if(abs(lambda(indices(m))) < epsilon) {
            M = m;
            break;
        }
    }
//    cout << min(abs(lambda)) << endl;
//    cout << "hei" << endl;
//    cout << lambda << endl;
//    M = 63;
    if(M < 0) {
        cerr << "MfLowRankApproximation:: no eigenvalues < epsilon found."
             << " Try setting epsilon to a higher number" << endl;
        exit(EXIT_FAILURE);
    }
    eigenval = zeros(M);
    for(int m=0; m <M; m++) {
        eigenval(m) = lambda(indices(m));
    }

    // Calculating  the U matrix
    U = zeros(nGrid, M);
    for(int m=0; m < M; m++) {
        for(uint j=0; j<h.n_rows; j++) {
            U(j,m) = 0;
            for(uint i=0; i<h.n_cols; i++) {
                U(j,m) += h(j,i)*QU(i,indices(m));
            }
        }
    }
    cout << "MfLowRankApproximation:: Trunction of eigenvalues at M = " << M << endl;

#if 1 // For testing the low rank approximation's accuracy
    mat appV = zeros(nGrid, nGrid);
    for(int i=0; i<nGrid; i++) {
        for(int j=0; j<nGrid; j++) {
            appV(i,j) = 0;
            for(int m=0; m<M; m++) {
                appV(i,j) += eigenval(m)*U(i,m)*U(j,m);
            }
        }
    }
    mat diffV = abs(Vxy - appV);
    cout << "max_err = " << max(max(abs(Vxy - appV))) << endl;

    diffV.save("../DATA/diffV.mat");
    appV.save("../DATA/Vapp.mat");
    Vxy.save("../DATA/Vex.mat");
    cout << nGrid << endl;
//    exit(EXIT_SUCCESS);

#endif
    cout << "test" << endl;
    Vm = zeros<cx_vec>(M);
    Vqr = zeros<cx_vec>(nGrid);
}