Back
Decomposer
Overview
The Decomposer is the abstract base class for all attribute decomposition strategies.
It defines the interface that concrete decomposers (like Components and Coordinates)
must implement. You can also create custom decomposers by inheriting from GenDecomposer<Derived>.
Include
#include <dataframe/attributes/Manager.h> // Decomposer is defined here
Decomposer Base Class
Decomposer Interface
namespace df::attributes {
class Decomposer {
public:
virtual ~Decomposer() = default;
// Create a polymorphic clone of this decomposer
virtual std::unique_ptr<Decomposer> clone() const = 0;
// Get decomposed attribute names for a given serie
virtual Strings names(
const Dataframe& dataframe,
DecompDimension targetDim,
const SerieBase& serie,
const String& name) const = 0;
// Extract a specific decomposed attribute
virtual Serie<double> serie(
const Dataframe& dataframe,
DecompDimension targetDim,
const std::string& name) const = 0;
protected:
// Get component count for a given type
template <typename T>
static size_t getComponentCount();
// Extract a single component from a serie at a given index
template <typename T>
static Serie<double> extractComponent(
const Serie<T>& serie, size_t index);
};
}
| Method | Description |
|---|---|
clone() | Creates a deep copy of the decomposer for polymorphic ownership |
names() | Returns all decomposed attribute names for a serie at the given dimension |
serie() | Extracts a specific component as Serie<double> |
getComponentCount<T>() | Returns the number of scalar components in type T |
extractComponent<T>() | Extracts the i-th scalar component from a typed serie |
GenDecomposer (CRTP Helper)
GenDecomposer<C> uses the Curiously Recurring Template Pattern to provide automatic
clone() and forwarding implementations. Derive from this instead of Decomposer directly.
GenDecomposer Template
namespace df::attributes {
template <typename C>
class GenDecomposer : public Decomposer {
public:
// Automatic clone via CRTP
std::unique_ptr<Decomposer> clone() const override;
// Forwards to derived class names() implementation
Strings names(const Dataframe&, DecompDimension,
const SerieBase&, const String&) const override;
// Forwards to derived class serie() implementation
Serie<double> serie(const Dataframe&, DecompDimension,
const std::string&) const override;
};
}
Creating a Custom Decomposer
Custom Decomposer Example
#include <dataframe/attributes/Manager.h>
using namespace df;
using namespace df::attributes;
// Custom decomposer that extracts magnitude from vectors
class MagnitudeDecomposer : public GenDecomposer<MagnitudeDecomposer> {
public:
Strings names(
const Dataframe& dataframe,
DecompDimension targetDim,
const SerieBase& serie,
const String& name) const override
{
if (targetDim == DecompDimension::Scalar) {
return {name + "_mag"};
}
return {};
}
Serie<double> serie(
const Dataframe& dataframe,
DecompDimension targetDim,
const std::string& name) const override
{
// Parse the base name (remove "_mag" suffix)
auto baseName = name.substr(0, name.size() - 4);
auto& base = dataframe.get<Vector3D>(baseName);
return base.map([](const Vector3D& v, size_t) {
return std::sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
});
}
};
// Usage
Manager manager(dataframe);
manager.addDecomposer(MagnitudeDecomposer());
auto mag = manager.getSerie<double>("velocity_mag");
Built-in Decomposers
| Decomposer | Purpose | Naming Pattern |
|---|---|---|
Components |
Decomposes vectors, matrices, and tensors into individual scalar components | Vectors: Px, Py, PzMatrices: M11, M12, ...Stress: Sxx, Sxy, ... |
Coordinates |
Spatial coordinate decomposition for vector types | P_x, P_y, P_z (customizable) |