# Eigen Analysis

The principal components (PC) transform (also known as the Karhunen-Loeve transform) is a spectral rotation that takes spectrally correlated image data and outputs uncorrelated data. The PC transform accomplishes this by diagonalizing the input band correlation matrix through Eigen-analysis. To do this in Earth Engine, use a covariance reducer on an array image and the `eigen()` command on the resultant covariance array. Consider the following function for that purpose (an example of it in application is available as a Code Editor script and a Colab notebook).

### Code Editor (JavaScript)

```var getPrincipalComponents = function(centered, scale, region) {
// Collapse the bands of the image into a 1D array per pixel.
var arrays = centered.toArray();

// Compute the covariance of the bands within the region.
var covar = arrays.reduceRegion({
reducer: ee.Reducer.centeredCovariance(),
geometry: region,
scale: scale,
maxPixels: 1e9
});

// Get the 'array' covariance result and cast to an array.
// This represents the band-to-band covariance within the region.
var covarArray = ee.Array(covar.get('array'));

// Perform an eigen analysis and slice apart the values and vectors.
var eigens = covarArray.eigen();

// This is a P-length vector of Eigenvalues.
var eigenValues = eigens.slice(1, 0, 1);
// This is a PxP matrix with eigenvectors in rows.
var eigenVectors = eigens.slice(1, 1);

// Convert the array image to 2D arrays for matrix computations.
var arrayImage = arrays.toArray(1);

// Left multiply the image array by the matrix of eigenvectors.
var principalComponents = ee.Image(eigenVectors).matrixMultiply(arrayImage);

// Turn the square roots of the Eigenvalues into a P-band image.
var sdImage = ee.Image(eigenValues.sqrt())
.arrayProject([0]).arrayFlatten([getNewBandNames('sd')]);

// Turn the PCs into a P-band image, normalized by SD.
return principalComponents
// Throw out an an unneeded dimension, [[]] -> [].
.arrayProject([0])
// Make the one band array image a multi-band image, [] -> image.
.arrayFlatten([getNewBandNames('pc')])
// Normalize the PCs by their SDs.
.divide(sdImage);
};```

Python setup

See the Python Environment page for information on the Python API and using `geemap` for interactive development.

```import ee
import geemap.core as geemap```

### Colab (Python)

```def get_principal_components(centered, scale, region):
# Collapse bands into 1D array
arrays = centered.toArray()

# Compute the covariance of the bands within the region.
covar = arrays.reduceRegion(
reducer=ee.Reducer.centeredCovariance(),
geometry=region,
scale=scale,
maxPixels=1e9,
)

# Get the 'array' covariance result and cast to an array.
# This represents the band-to-band covariance within the region.
covar_array = ee.Array(covar.get('array'))

# Perform an eigen analysis and slice apart the values and vectors.
eigens = covar_array.eigen()

# This is a P-length vector of Eigenvalues.
eigen_values = eigens.slice(1, 0, 1)
# This is a PxP matrix with eigenvectors in rows.
eigen_vectors = eigens.slice(1, 1)

# Convert the array image to 2D arrays for matrix computations.
array_image = arrays.toArray(1)

# Left multiply the image array by the matrix of eigenvectors.
principal_components = ee.Image(eigen_vectors).matrixMultiply(array_image)

# Turn the square roots of the Eigenvalues into a P-band image.
sd_image = (
ee.Image(eigen_values.sqrt())
.arrayProject([0])
.arrayFlatten([get_new_band_names('sd')])
)

# Turn the PCs into a P-band image, normalized by SD.
return (
# Throw out an an unneeded dimension, [[]] -> [].
principal_components.arrayProject([0])
# Make the one band array image a multi-band image, [] -> image.
.arrayFlatten([get_new_band_names('pc')])
# Normalize the PCs by their SDs.
.divide(sd_image)
)

```

The input to the function is a mean zero image, a scale and a region over which to perform the analysis. Note that the input imagery first needs to be converted to a 1-D array image and then reduced using `ee.Reducer.centeredCovariance()`. The array returned by this reduction is the symmetric variance-covariance matrix of the input. Use the `eigen()` command to get the eigenvalues and eigenvectors of the covariance matrix. The matrix returned by `eigen()` contains the eigenvalues in the 0-th position of the 1-axis. As shown in the earlier function, use `slice()` to separate the eigenvalues and the eigenvectors. Each element along the 0-axis of the eigenVectors matrix is an eigenvector. As in the tasseled cap (TC) example, perform the transformation by matrix multiplying the `arrayImage` by the eigenvectors. In this example, each eigenvector multiplication results in a PC.

[{ "type": "thumb-down", "id": "missingTheInformationINeed", "label":"Missing the information I need" },{ "type": "thumb-down", "id": "tooComplicatedTooManySteps", "label":"Too complicated / too many steps" },{ "type": "thumb-down", "id": "outOfDate", "label":"Out of date" },{ "type": "thumb-down", "id": "samplesCodeIssue", "label":"Samples / code issue" },{ "type": "thumb-down", "id": "otherDown", "label":"Other" }]
[{ "type": "thumb-up", "id": "easyToUnderstand", "label":"Easy to understand" },{ "type": "thumb-up", "id": "solvedMyProblem", "label":"Solved my problem" },{ "type": "thumb-up", "id": "otherUp", "label":"Other" }]