using MathNet.Numerics.LinearAlgebra;
static void Main(string[] args)
static void MainApplication()
Console.WriteLine("-------------------------------------------------------");
Console.WriteLine("- Welcome to PCA - EigneValue Calculator -");
Console.WriteLine("- Created by Omar Abahsain - 20110708 -");
Console.WriteLine("- ITCIS792 - Statistics Techniques - 8th Nov 2024 -");
Console.WriteLine("-------------------------------------------------------");
Console.WriteLine("What would you like to do?");
Console.WriteLine("1. Enter Own Data Points, calculate covaroience and eigenvalues");
Console.WriteLine("2. Load Sample Data Points, calculate covarience and eigenvalues.");
Console.WriteLine("3. Exit");
Console.Write("I want Choice: ");
var input = Console.ReadLine();
Console.WriteLine("Please select a choice, 1 or 2 or 3...");
Boolean isNumeric = int.TryParse(input, out x);
Console.WriteLine("Invalid input, expected numeric value, 1 or 2 or 3...");
if (x != 1 && x != 2 && x != 3)
Console.WriteLine("Invalid choice, 1 or 2 or 3...");
Console.WriteLine("Have a Good Day :)");
static void SampleMatrix() {
Console.WriteLine("-------------------------------");
double[,] data = new double[,]
Console.WriteLine("Data points (rows are points, columns are dimensions):");
Console.WriteLine("\nCalculating Covariance Matrix...");
double[,] covarianceMatrix = MatrixOperations.CalculateCovarianceMatrix(data);
Console.WriteLine("\nCovariance Matrix:");
PrintMatrix(covarianceMatrix);
Console.WriteLine("\nCalculating Eigenvalues and Eigenvectors...");
var (eigenvalues, eigenvectors) = PCAHelper.CalculateEigen(covarianceMatrix);
Console.WriteLine("\nEigenvalues:");
foreach (var eigenvalue in eigenvalues)
Console.WriteLine(eigenvalue);
Console.WriteLine("\nEigenvectors:");
PrintMatrix(eigenvectors);
Console.WriteLine("\n-----------------------------------------");
Console.WriteLine("Press Any Key to return back to Menu...");
static void CustomMatrix()
int cols = 0; int rows = 0;
Console.WriteLine("-------------------------------");
Console.WriteLine("How many dimensions are there in the data points?\n(ex: {3,4,5} means 3 dimensions) - Enter E to exit to Menu");
var dimensions = Console.ReadLine();
dimensions = dimensions.Trim();
if (dimensions.ToLower() == "e") {
Boolean dimensionIsNumeric = int.TryParse(dimensions, out cols);
if (dimensions == null || !dimensionIsNumeric)
Console.WriteLine("Invalid entry, numeric value expected");
Console.WriteLine("-------------------------------");
Console.WriteLine("Dimension of "+dimensions+" has been set.");
Console.WriteLine("How many data points do you have? - Enter E to exit to Menu");
var points = Console.ReadLine();
if (points.ToLower() == "e")
Boolean pointsIsNumeric = int.TryParse(points, out rows);
if (points == null || !pointsIsNumeric)
Console.WriteLine("Invalid entry, numeric value expected");
var Example = generateExample(cols);
double[,] data = new double[rows, cols];
for (int i = 0; i <= rows; i++)
Console.WriteLine("-------------------------------");
Console.WriteLine("Dimension of " + dimensions + " has been set.");
Console.WriteLine("Expecting " + points + " to be entered.");
Console.WriteLine("Single Data point Example: " + Example);
Console.WriteLine("Note: Enter E to exit to Menu");
Console.WriteLine("-------------------------------");
Console.WriteLine("Current Entries:");
PrintMatrixByRows(data, i);
Console.WriteLine("-------------------------------");
Console.Write("Calculation will begin...");
Console.WriteLine("Enter data points number [" + (i+1) + " out of "+rows+"] saperated by a comma of dimension " + dimensions + ":");
var DataPoint = Console.ReadLine();
DataPoint = DataPoint.Trim();
if (DataPoint.ToLower() == "e")
Console.WriteLine("Invalid data point, expected data point dimension to be " + dimensions + ", and as example ("+Example+"), received empty input");
var DataPointArray = DataPoint.Split(',');
var DataPointLength = DataPointArray.Length;
if (DataPointLength != cols)
Console.WriteLine("Invalid data point, expected data point dimension to be "+dimensions+", received "+ DataPoint);
if (!ValidateDataPoints(DataPointArray)) {
Console.WriteLine("Invalid data point, expected data point as example ("+Example+") and recieved "+DataPoint);
for (int j = 0; j < cols; j++)
data[i, j] = double.Parse(DataPointArray[j]);
Console.WriteLine("-------------------------------");
Console.WriteLine("You have provided the following Data points (rows are points, columns are dimensions):");
Console.WriteLine("\nCalculating Covariance Matrix...");
double[,] covarianceMatrix = MatrixOperations.CalculateCovarianceMatrix(data);
Console.WriteLine("\nCovariance Matrix:");
PrintMatrix(covarianceMatrix);
Console.WriteLine("\nCalculating Eigenvalues and Eigenvectors...");
var (eigenvalues, eigenvectors) = PCAHelper.CalculateEigen(covarianceMatrix);
Console.WriteLine("\nEigenvalues:");
foreach (var eigenvalue in eigenvalues)
Console.WriteLine(eigenvalue);
Console.WriteLine("\nEigenvectors:");
PrintMatrix(eigenvectors);
Console.WriteLine("\n-----------------------------------------");
Console.WriteLine("Press Any Key to return back to Menu...");
static String generateExample(int cols) {
Random random = new Random();
for (int i = 0; i < cols; i++) {
example += random.Next(1, 100);
return example.Remove(example.Length - 1);
static Boolean ValidateDataPoints(String[] DataPoints) {
for (int i = 0; i < DataPoints.Length; i++) {
valid = int.TryParse(DataPoints[i], out x);
static void PrintMatrix(double[,] matrix)
int rows = matrix.GetLength(0);
int cols = matrix.GetLength(1);
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
Console.Write($"{matrix[i, j]:F2}\t");
static void PrintMatrixByRows(double[,] matrix, int currentRow)
int cols = matrix.GetLength(1);
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
Console.Write($"{matrix[i, j]:F2}\t");
public static class MatrixOperations
public static double[,] CalculateCovarianceMatrix(double[,] data)
int numPoints = data.GetLength(0);
int numDimensions = data.GetLength(1);
double[,] covarianceMatrix = new double[numDimensions, numDimensions];
double[] mean = new double[numDimensions];
for (int j = 0; j < numDimensions; j++)
for (int i = 0; i < numPoints; i++)
for (int i = 0; i < numDimensions; i++)
for (int j = 0; j < numDimensions; j++)
for (int k = 0; k < numPoints; k++)
sum += (data[k, i] - mean[i]) * (data[k, j] - mean[j]);
covarianceMatrix[i, j] = sum / (numPoints - 1);
public static class PCAHelper
public static (double[] eigenvalues, double[,] eigenvectors) CalculateEigen(double[,] covarianceMatrix)
var matrix = Matrix<double>.Build.DenseOfArray(covarianceMatrix);
var eigenvalues = evd.EigenValues.Real().ToArray();
var eigenvectors = evd.EigenVectors.ToArray();
return (eigenvalues, eigenvectors);