Skip to main content

Overview

The LDA class implements Linear Discriminant Analysis, a supervised dimensionality reduction technique that finds a linear combination of features to best separate multiple classes. It computes class means, scatter matrices, and a projection matrix for classification. Namespace: mlpp::classifiers Template parameters:
  • Scalar: Numeric type for computations (e.g., float, double)
  • LabelIndex: Integer type for class labels (default: int)

Constructor

LDA

Construct an LDA classifier.
template<typename Scalar, typename LabelIndex = int>
LDA();
Default constructor that initializes an empty LDA model.
#include "LDA.h"

using namespace mlpp::classifiers;

LDA<double> lda;

Methods

fit

Fit the LDA model to training data.
void fit(const Matrix& X, const Labels& labels, int num_components = -1);
X
const Matrix&
Training data matrix of shape (n_samples × n_features)
labels
const Labels&
Integer class labels vector of shape (n_samples)
num_components
int
default:"-1"
Number of components to compute. If -1, defaults to num_classes - 1
This method computes:
  • Class mean vectors
  • Within-class scatter matrix
  • Between-class scatter matrix
  • Projection matrix via generalized eigenvalue decomposition
Eigen::MatrixXd X(100, 4);  // 100 samples, 4 features
Eigen::VectorXi y(100);      // Class labels

// ... populate X and y ...

LDA<double, int> lda;
lda.fit(X, y, 2);  // Project to 2 dimensions

transform

Transform data using the learned projection matrix.
Matrix transform(const Matrix& X) const;
X
const Matrix&
Data matrix to transform of shape (n_samples × n_features)
return
Matrix
Transformed data of shape (n_samples × n_components)
Projects the input data onto the discriminant axes learned during training.
Eigen::MatrixXd X_test(20, 4);  // 20 test samples
// ... populate X_test ...

Eigen::MatrixXd X_transformed = lda.transform(X_test);
// X_transformed is shape (20 × 2)

compute_projection_matrix

Compute the projection matrix from scratch.
void compute_projection_matrix(int num_components = -1);
num_components
int
default:"-1"
Number of discriminant components. If -1, uses num_classes - 1
This method is called internally by fit() but can be invoked separately to recompute the projection with a different number of components.
lda.compute_projection_matrix(3);  // Recompute with 3 components

projection_matrix

Get the learned projection matrix.
const Matrix& projection_matrix() const;
return
const Matrix&
Projection matrix of shape (n_features × n_components)
auto W = lda.projection_matrix();
std::cout << "Projection shape: " << W.rows() << " × " << W.cols() << std::endl;

mean_vectors

Get the class mean vectors.
const Matrix& mean_vectors() const;
return
const Matrix&
Matrix of mean vectors of shape (n_features × num_classes)
Each column represents the mean feature vector for one class.
auto means = lda.mean_vectors();
std::cout << "Class 0 mean: " << means.col(0).transpose() << std::endl;

num_classes

Get the number of classes.
int num_classes() const;
return
int
Number of classes in the training data
int k = lda.num_classes();

Type aliases

using Matrix = Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>;
using Vector = Eigen::Matrix<Scalar, Eigen::Dynamic, 1>;
using Labels = Eigen::Matrix<LabelIndex, Eigen::Dynamic, 1>;

Example usage

#include "LDA.h"
#include <Eigen/Dense>
#include <iostream>

using namespace mlpp::classifiers;

int main() {
    // Generate synthetic 3-class data
    const int n_samples = 150;
    const int n_features = 4;
    const int n_classes = 3;
    
    Eigen::MatrixXd X = Eigen::MatrixXd::Random(n_samples, n_features);
    Eigen::VectorXi y(n_samples);
    
    // Assign class labels
    for (int i = 0; i < n_samples; ++i) {
        y(i) = i / 50;  // Classes 0, 1, 2
    }
    
    // Train LDA
    LDA<double, int> lda;
    lda.fit(X, y, 2);  // Reduce to 2 dimensions
    
    std::cout << "Number of classes: " << lda.num_classes() << std::endl;
    std::cout << "Projection matrix shape: " 
              << lda.projection_matrix().rows() << " × " 
              << lda.projection_matrix().cols() << std::endl;
    
    // Transform data
    Eigen::MatrixXd X_lda = lda.transform(X);
    std::cout << "Transformed data shape: " 
              << X_lda.rows() << " × " << X_lda.cols() << std::endl;
    
    // Access class means
    auto means = lda.mean_vectors();
    for (int i = 0; i < n_classes; ++i) {
        std::cout << "Class " << i << " mean: " 
                  << means.col(i).transpose() << std::endl;
    }
    
    return 0;
}

Build docs developers (and LLMs) love