예제 #1
0
// Decompose computes an m-by-n matrix M for an m-by-m covariance matrix Σ such
// that, for an n-element vector X with uncorrelated components, M * X is an
// m-element vector whose components are correlated according to Σ. The
// function reduces the number of dimensions from m to n such that a certain
// portion of the variance is preserved, which is controlled by λ ∈ (0, 1].
func Decompose(Σ []float64, m uint, λ float64) ([]float64, uint, error) {
	U, Λ, err := decomposition.CovPCA(Σ, m, math.Sqrt(math.Nextafter(1, 2)-1))
	if err != nil {
		return nil, 0, err
	}

	n := m

	// NOTE: Λ is in the descending order and nonnegative.
	var cum, sum float64
	for i := uint(0); i < m; i++ {
		sum += Λ[i]
	}
	for i := uint(0); i < m; i++ {
		cum += Λ[i]
		if cum/sum >= λ {
			n = i + 1
			break
		}
	}

	for i := uint(0); i < n; i++ {
		coef := math.Sqrt(Λ[i])
		for j := uint(0); j < m; j++ {
			U[i*m+j] *= coef
		}
	}

	return U[:m*n], n, nil
}
예제 #2
0
func TestCorrelateLarge(t *testing.T) {
	_, application, _ := system.Load("fixtures/016_160.tgff")

	ε := math.Sqrt(math.Nextafter(1.0, 2.0) - 1.0)
	R := Compute(application, index(160), 5)
	_, _, err := decomposition.CovPCA(R, 160, ε)
	assert.Success(err, t)
}
예제 #3
0
func TestCorrelateSmall(t *testing.T) {
	_, application, _ := system.Load("fixtures/002_020.tgff")

	R := Compute(application, index(20), 2)
	_, _, err := decomposition.CovPCA(R, 20, 0)
	assert.Success(err, t)

	R = Compute(application, index(1), 2)
	assert.Equal(R, []float64{1.0}, t)
}
예제 #4
0
// Decompose computes an m-by-n matrix C and an n-by-m matrix D given an m-by-m
// covariance matrix Σ such that (a) for an n-element vector Z with uncorrelated
// components, C * X is an m-element vector whose components are correlated
// according to Σ, and (b) for an m-element vector X with correlated components
// according to Σ, D * X is an n-element vector with uncorrelated components.
// The function reduces the number of dimensions from m to n such that a certain
// portion of the variance is preserved, which is controlled by λ ∈ (0, 1].
//
// Internally the function relies on decomposition.CovPCA and returns its
// outputs as well (the principal components and vectors of Σ).
func Decompose(Σ []float64, m uint, λ, ε float64) (C []float64, D []float64,
	U []float64, Λ []float64, err error) {

	U, Λ, err = decomposition.CovPCA(Σ, m, ε)
	if err != nil {
		return nil, nil, nil, nil, err
	}

	n := m

	var cum, sum float64
	for i := uint(0); i < m; i++ {
		sum += Λ[i]
	}
	for i := uint(0); i < m; i++ {
		cum += Λ[i]
		if cum/sum >= λ {
			n = i + 1
			break
		}
	}

	C = make([]float64, m*n)
	D = make([]float64, n*m)

	for i := uint(0); i < n; i++ {
		σ := math.Sqrt(Λ[i])
		for j := uint(0); j < m; j++ {
			ρ := U[i*m+j]
			C[i*m+j] = ρ * σ
			D[j*n+i] = ρ / σ
		}
	}

	return
}