jeudi 12 novembre 2020

Generation of polynomial features in C++98

I am trying to generate polynomial features of an array of 27 floats to obtain an array of 405 floats as output. I am working on an old version of C++98 (no upgrade possible). I used to use this piece of code in C++11 to generate those features:

#include <vector>
#include <iostream>
//#include <numeric>

using namespace std;

template <class T>
std::vector<T> polynomialFeatures( const std::vector<T>& input, unsigned int 
degree, bool interaction_only, bool include_bias )
{
    std::vector<T> new_chunk; // declare new_chunk here
    std::vector<T> features = input;
    std::vector<T> prev_chunk = input;
    std::vector<size_t> indices( input.size() );

   for ( int d = 1 ; d < degree ; ++d )
    {
       for ( size_t i = 0 ; i < input.size() - ( interaction_only ? d : 0 ) ; ++i )
        {
            // Store the index where to start multiplying with the current component at the next degree up:
            size_t next_index = new_chunk.size();
           for ( auto coef_it = prev_chunk.begin() + indices[i + ( interaction_only ? 1 : 0 )] ; coef_it != prev_chunk.end() ; ++coef_it )
            {
                new_chunk.push_back( input[i]**coef_it );
            }
            indices[i] = next_index;
        }
        // Extend the feature vector with the new chunk of features:
        features.reserve( features.size() + std::distance( new_chunk.begin(), 
new_chunk.end() ) );
        features.insert( features.end(), new_chunk.begin(), new_chunk.end() );

        prev_chunk = new_chunk;
    }
    if ( include_bias )
        features.insert( features.begin(), 1 );

    return features;
}

And due to my limited Knowledge in C++, I am having difficulties to adapt this function in C++98. I tried the following by removing the vectors which I don't need:

float polynomialFeatures( float input[27], unsigned int 
degree, bool interaction_only, bool include_bias )
{
    float new_chunk; // declare new_chunk here
    float  features = input;
    float  prev_chunk = input;
    float  indices( input.size() );

   for ( int d = 1 ; d < degree ; ++d )
    {
       for ( size_t i = 0 ; i < input.size() - ( interaction_only ? d : 0 ) ; ++i )
        {
            // Store the index where to start multiplying with the current component at the next degree up:
            size_t next_index = new_chunk.size();
           for ( auto coef_it = prev_chunk.begin() + indices[i + ( interaction_only ? 1 : 0 )] ; coef_it != prev_chunk.end() ; ++coef_it )
            {
                new_chunk.push_back( input[i]**coef_it );
            }
            indices[i] = next_index;
        }
        // Extend the feature vector with the new chunk of features:
        features.reserve( features.size() + std::distance( new_chunk.begin(), 
new_chunk.end() ) );
        features.insert( features.end(), new_chunk.begin(), new_chunk.end() );

        prev_chunk = new_chunk;
    }
    if ( include_bias )
        features.insert( features.begin(), 1 );

    return features;
}

And I get those errors:

 In function 'float polynomialFeatures(float*, unsigned int, bool, bool)':
 error: cannot convert 'float*' to 'float' in initialization
     float  features = input;
                       ^
 error: cannot convert 'float*' to 'float' in initialization
     float  prev_chunk = input;
                         ^
 error: request for member 'size' in 'input', which is of non-class type 'float*'
     float  indices( input.size() );
 warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    for ( int d = 1 ; d < degree ; ++d )
 error: request for member 'size' in 'input', which is of non-class type 'float*'
        for ( size_t i = 0 ; i < input.size() - ( interaction_only ? d : 0 ) ; ++i )
 error: request for member 'size' in 'new_chunk', which is of non-class type 'float'
             size_t next_index = new_chunk.size();   
 warning: 'auto' changes meaning in C++11; please remove it [-Wc++0x-compat]
            for ( auto coef_it = prev_chunk.begin() + indices[i + ( interaction_only ? 1 : 0 )] ; coef_it != prev_chunk.end() ; ++coef_it )
 error: 'coef_it' does not name a type
            for ( auto coef_it = prev_chunk.begin() + indices[i + ( interaction_only ? 1 : 0 )] ; coef_it != prev_chunk.end() ; ++coef_it )
 error: expected ';' before 'coef_it'
            for ( auto coef_it = prev_chunk.begin() + indices[i + ( interaction_only ? 1 : 0 )] ; coef_it != prev_chunk.end() ; ++coef_it )           
 error: 'coef_it' was not declared in this scope
 error: request for member 'end' in 'prev_chunk', which is of non-class type 'float'
            for ( auto coef_it = prev_chunk.begin() + indices[i + ( interaction_only ? 1 : 0 )] ; coef_it != prev_chunk.end() ; ++coef_it )               
 error: request for member 'push_back' in 'new_chunk', which is of non-class type 'float'
                 new_chunk.push_back( input[i]**coef_it );
 error: invalid types 'float[size_t {aka long unsigned int}]' for array subscript
             indices[i] = next_index;
 error: request for member 'reserve' in 'features', which is of non-class type 'float'
         features.reserve( features.size() + std::distance( new_chunk.begin(), 
 error: request for member 'size' in 'features', which is of non-class type 'float'
         features.reserve( features.size() + std::distance( new_chunk.begin(), 
 error: 'distance' is not a member of 'std'
         features.reserve( features.size() + std::distance( new_chunk.begin(), 
 error: request for member 'begin' in 'new_chunk', which is of non-class type 'float'
         features.reserve( features.size() + std::distance( new_chunk.begin(),                       
 error: request for member 'end' in 'new_chunk', which is of non-class type 'float'
 new_chunk.end() ) );
 error: request for member 'insert' in 'features', which is of non-class type 'float'
         features.insert( features.end(), new_chunk.begin(), new_chunk.end() );
 error: request for member 'end' in 'features', which is of non-class type 'float'
         features.insert( features.end(), new_chunk.begin(), new_chunk.end() );
 error: request for member 'begin' in 'new_chunk', which is of non-class type 'float'
         features.insert( features.end(), new_chunk.begin(), new_chunk.end() );    
 error: request for member 'end' in 'new_chunk', which is of non-class type 'float'
         features.insert( features.end(), new_chunk.begin(), new_chunk.end() );
 error: request for member 'insert' in 'features', which is of non-class type 'float'
         features.insert( features.begin(), 1 );
 error: request for member 'begin' in 'features', which is of non-class type 'float'
         features.insert( features.begin(), 1 );

I also would like to multiply each of the generated features during the features generation procedure with a coefficient of another array of floats with 405 values and add all of those multiplications to obtain at the end the scalar product of both arrays ( the polynomial features array 'features[405]' and the already known array 'abc[405]'

Aucun commentaire:

Enregistrer un commentaire