<commit_before>#include <cmath>
#include <Eigen/Dense>
#include <gtest/gtest.h>

class ReferenceFilter
{
public:
    ReferenceFilter( unsigned inputCount, unsigned outputCount )
        : mW( Eigen::MatrixXf::Random( outputCount, inputCount ) )
    {}

    Eigen::VectorXf operator()( Eigen::VectorXf inputs )
    {
        return mW * inputs;
    }

    Eigen::MatrixXf mW;
};

class Model
{
    const unsigned kInputCount = 100;
    const unsigned kOutputCount = 3;
    const float kMaxAmplitude = 1.0f;
    const float kMaxFrequency = 10.0f;
    const float kStep = 0.1f * 1.0f / kMaxFrequency;

public:
    Model()
        : mAmplitude( kMaxAmplitude / 2.0f *
            ( Eigen::VectorXf::Random( kInputCount ).array() + 1.0f ) )
        , mOmega( kMaxFrequency / 2.0f *
            ( Eigen::VectorXf::Random( kInputCount ).array() + 1.0f ) )
        , mInput( kInputCount )
        , mW( Eigen::MatrixXf::Random( kOutputCount, kInputCount ) )
        , mOutput( kOutputCount )
        , mReferenceFilter( kInputCount, kOutputCount )
        , mReferenceOutput( kOutputCount )
        , mTime( 0.0f )
    {}

    void Update()
    {
        mTime += kStep;
        mInput = mAmplitude.array() * ( mOmega.array() * mTime ).unaryExpr(
            std::ptr_fun< float, float >( std::sin ) );
        mOutput = mW * mInput;
        mReferenceOutput = mReferenceFilter( mInput );
    }

    Eigen::VectorXf mAmplitude;
    Eigen::VectorXf mOmega;
    Eigen::VectorXf mInput;
    Eigen::MatrixXf mW;
    Eigen::VectorXf mOutput;
    ReferenceFilter mReferenceFilter;
    Eigen::VectorXf mReferenceOutput;
    float mTime;
};

TEST( AdaptiveFilter, LMS )
{
    const unsigned kStepCount = 10000;
    const float kTrainStep = 0.1f;

    Model model;

    for ( int i = 0; i < kStepCount; ++ i )
    {
        model.Update();
        Eigen::VectorXf error = model.mReferenceOutput - model.mOutput;
        model.mW += ( kTrainStep * error * model.mInput.transpose() /
            model.mInput.squaredNorm() );
    }
}
<commit_msg>esn : tests : AdaptiveFilter : NLMS : renamed test-case LMS -> NLMS<commit_after>#include <cmath>
#include <Eigen/Dense>
#include <gtest/gtest.h>

class ReferenceFilter
{
public:
    ReferenceFilter( unsigned inputCount, unsigned outputCount )
        : mW( Eigen::MatrixXf::Random( outputCount, inputCount ) )
    {}

    Eigen::VectorXf operator()( Eigen::VectorXf inputs )
    {
        return mW * inputs;
    }

    Eigen::MatrixXf mW;
};

class Model
{
    const unsigned kInputCount = 100;
    const unsigned kOutputCount = 3;
    const float kMaxAmplitude = 1.0f;
    const float kMaxFrequency = 10.0f;
    const float kStep = 0.1f * 1.0f / kMaxFrequency;

public:
    Model()
        : mAmplitude( kMaxAmplitude / 2.0f *
            ( Eigen::VectorXf::Random( kInputCount ).array() + 1.0f ) )
        , mOmega( kMaxFrequency / 2.0f *
            ( Eigen::VectorXf::Random( kInputCount ).array() + 1.0f ) )
        , mInput( kInputCount )
        , mW( Eigen::MatrixXf::Random( kOutputCount, kInputCount ) )
        , mOutput( kOutputCount )
        , mReferenceFilter( kInputCount, kOutputCount )
        , mReferenceOutput( kOutputCount )
        , mTime( 0.0f )
    {}

    void Update()
    {
        mTime += kStep;
        mInput = mAmplitude.array() * ( mOmega.array() * mTime ).unaryExpr(
            std::ptr_fun< float, float >( std::sin ) );
        mOutput = mW * mInput;
        mReferenceOutput = mReferenceFilter( mInput );
    }

    Eigen::VectorXf mAmplitude;
    Eigen::VectorXf mOmega;
    Eigen::VectorXf mInput;
    Eigen::MatrixXf mW;
    Eigen::VectorXf mOutput;
    ReferenceFilter mReferenceFilter;
    Eigen::VectorXf mReferenceOutput;
    float mTime;
};

TEST( AdaptiveFilter, NLMS )
{
    const unsigned kStepCount = 10000;
    const float kTrainStep = 0.1f;

    Model model;

    for ( int i = 0; i < kStepCount; ++ i )
    {
        model.Update();
        Eigen::VectorXf error = model.mReferenceOutput - model.mOutput;
        model.mW += ( kTrainStep * error * model.mInput.transpose() /
            model.mInput.squaredNorm() );
    }
}

{'fraction_non_alphanumeric': 0.12095400340715502, 'fraction_numerical': 0.015088829398880507, 'mean_word_length': 2.53396388650043, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '640155', 'n_tokens_mistral': 1458, 'n_tokens_neox': 1376, 'n_words': 301}