PFS Complete Workflow#

This page covers the complete workflow for NeurEco Parametric Frequency Sweep (PFS) models: data preparation, building, evaluating, and exporting.

Data Preparation#

Data Structure#

PFS models require:

  • Input data: Frequency and parameters — shape (n_samples, n_inputs) where n_inputs >= 2

  • Output data: Complex frequency responses — shape (n_samples, n_outputs)

Warning

The first column of input data must ALWAYS be the frequency.

This requirement applies in all cases:

  • During training

  • During evaluation

  • Even when evaluating at a single frequency (the frequency column must still be present)

The model expects frequency as input index 0 — this cannot be changed or omitted.

Data Types#

Data

Python/NumPy

CSV

Inputs

float64

float or double

Outputs

complex128

Complex notation (see below)

Complex Number Formats in CSV:

  • 0.1+0.1j — Standard Python notation

  • (0.1+0.1j) — With parentheses

  • (0.1,0.1) — Tuple notation (real, imag)

File Formats#

Use NumPy arrays or lists of arrays:

import numpy as np

# Load from .npy files
x_train = np.load('inputs_train.npy')
y_train = np.load('targets_train.npy')

# Or create programmatically
# Column 0: frequency, Column 1+: parameters
inputs = np.zeros((n_samples, n_inputs), dtype=np.float64)
outputs = np.zeros((n_samples, n_outputs), dtype=np.complex128)

Data Normalization#

NeurEco automatically normalizes PFS data:

Input normalization (per feature):

\[x_{normalized} = \frac{x - \min(x)}{\max(x) - \min(x)}\]

Output normalization (global):

\[y_{normalized} = \frac{y}{\max(|y|)}\]

Building a Model#

Starting a New Project

  1. Launch NeurEco

  2. Select Parametric Frequency Sweep

  3. Click New Project

Loading Data

  1. In the Build panel, click + next to Training files

  2. Select your input file (frequency + parameters)

  3. Select your output file (complex responses)

  4. Repeat for validation and test files if available

Build Parameters

Parameter

Description

Valid percentage

Percentage of training data for validation (if no validation files provided)

Reduced space dimension

Dimension of compressed output space (controls internal complexity)

Min enrichment steps

Minimum number of enrichment iterations

Max enrichment steps

Maximum number of enrichment iterations (upper limit)

Unsuccessful steps

Consecutive failures before early stopping

Enrichment rate

Rate of parameter addition per step (0 < rate <= 1)

Building

  1. Click BUILD

  2. Monitor progress in the Training panel

  3. Checkpoints are saved automatically

Parameter Reference#

Parameter

Default

Description

input_data

(required)

Training inputs. Shape: (n_samples, n_inputs), first column = frequency

output_data

(required)

Training outputs. Shape: (n_samples, n_outputs), dtype: complex

validation_input_data

None

Validation inputs (optional)

validation_output_data

None

Validation outputs (optional)

valid_percentage

33.33

Validation split (1–50%, used if no validation data)

reduced_space_dimension

5

Compressed output space dimension

min_enrichment_steps

10

Minimum enrichment iterations

max_enrichment_steps

200

Maximum enrichment iterations

unsuccessful_enrichment_steps

4

Failures before early stopping

enrichment_rate

0.2

Parameter addition rate (0 < rate <= 1)

Working with Checkpoints#

During training, NeurEco saves intermediate models. You can load and compare them:

model = Frequential.PFS()

# Get number of checkpointed models
n_models = model.get_number_of_networks_from_checkpoint("./model/pfs_checkpoint")
print(f"Found {n_models} checkpointed models")

# Evaluate each checkpoint
for i in range(n_models):
    model.load_model_from_checkpoint("./model/pfs_checkpoint", i)
    outputs = model.evaluate(x_test)
    error = model.compute_error(outputs, y_test)
    denom_size = model.get_denominator_size()
    print(f"Model {i}: error={100*error:.2f}%, denominator_size={denom_size}")

Evaluating a Model#

  1. Go to the Evaluation panel

  2. Load evaluation data

  3. Click Evaluate

  4. View results in the plot panel

  5. Check Metrics panel for error statistics

Input Sweep Analysis#

Analyze how one input affects the output while keeping others constant:

# Define a reference input sample
input_sample = np.array([100.0, 0.05, 1.0, 0.5])  # freq, param1, param2, param3

# Sweep the frequency (input_id=0) from 1 to 500 Hz
model.perform_input_sweep(
    input_feature=input_sample,
    input_id=0,              # Sweep frequency
    input_interval=[1, 500], # Range
    output_id=0,             # Which output to plot
    n_points=200,
    show=True,
    save_path="frequency_sweep.png"
)

Exporting a Model#

Export to FMU

status = model.export_fmu("./model/pfs_model.fmu")

if status == 0:
    print("Model exported to FMU successfully")

Note

FMU export requires a NeurEco Embed PFS license.

Save in Native Format

model.save("./model/pfs_model_copy.efnn")

Method Reference#

Method

Description

build(config)

Train a PFS model with the given configuration

load(path)

Load a saved model from disk

save(path)

Save the model to disk

evaluate(inputs)

Run inference on input data, returns complex outputs

compute_error(predictions, targets)

Compute L2 relative error between predictions and targets

get_input_count()

Get number of input features

get_output_count()

Get number of output features

get_denominator_size()

Get denominator size of the rational approximation

perform_input_sweep(...)

Sweep one input and visualize the response

export_fmu(path)

Export model to FMU format

get_number_of_networks_from_checkpoint(path)

Get number of models in a checkpoint

load_model_from_checkpoint(path, model_index)

Load a specific model from checkpoint

delete()

Free memory (call when done)

Best Practices#

  1. Always put frequency first: The first column of input data must be the frequency

  2. Use complex128 for outputs: Ensure your output data is complex128 dtype

  3. Explore checkpoints: Compare intermediate models to find the best accuracy/complexity trade-off

  4. Monitor denominator size: Larger denominators = more complex models, potentially better accuracy but slower inference

  5. Clean up: Call model.delete() when finished to free memory

Next Steps#