void LinearClassifier::Initialize( const SignalProperties& Input, const SignalProperties& /*Output*/ ) { const ParamRef& Classifier = Parameter( "Classifier" ); size_t numEntries = Classifier->NumRows(); mInputChannels.resize( numEntries ); mInputElements.resize( numEntries ); mOutputChannels.resize( numEntries ); mWeights.resize( numEntries ); for( size_t entry = 0; entry < numEntries; ++entry ) { mInputChannels[ entry ] = Input.ChannelIndex( Classifier( entry, 0 ) ); mInputElements[ entry ] = Input.ElementIndex( Classifier( entry, 1 ) ); mOutputChannels[ entry ] = Classifier( entry, 2 ) - 1; mWeights[ entry ] = Classifier( entry, 3 ); } }
void LinearClassifier::Preflight( const SignalProperties& Input, SignalProperties& Output ) const { // Determine the classifier matrix format: int controlSignalChannels = 0; const ParamRef& Classifier = Parameter( "Classifier" ); if( Classifier->NumColumns() != 4 ) bcierr << "Classifier parameter must have 4 columns " << "(input channel, input element, output channel, weight)" << endl; else { for( int row = 0; row < Classifier->NumRows(); ++row ) { if( Classifier( row, 2 ) < 1 ) bcierr << "Output channels must be positive integers" << endl; float ch = Input.ChannelIndex( Classifier( row, 0 ) ); if( ch < 0 ) bcierr << DescribeEntry( row, 0 ) << " points to negative input index" << endl; else if( ::floor( ch ) > Input.Channels() ) bcierr << "Channel specification in " << DescribeEntry( row, 0 ) << " exceeds number of input channels" << endl; if( ::fmod( ch, 1.0f ) > 1e-2 ) bciout << "Channel specification in physical units: " << DescribeEntry( row, 0 ) << " does not exactly meet a single channel" << endl; float el = Input.ElementIndex( Classifier( row, 1 ) ); if( el < 0 ) bcierr << DescribeEntry( row, 1 ) << " points to negative input index" << endl; if( ::floor( el ) > Input.Elements() ) bcierr << "Element (bin) specification in " << DescribeEntry( row, 1 ) << " exceeds number of input elements" << endl; if( ::fmod( el, 1.0f ) > 1e-2 ) bciout << "Element (bin) specification in physical units: " << DescribeEntry( row, 1 ) << " does not exactly meet a single element" << endl; int outputChannel = Classifier( row, 2 ); controlSignalChannels = max( controlSignalChannels, outputChannel ); } } // Requested output signal properties. Output = SignalProperties( controlSignalChannels, 1, Input.Type() ); // Output description. Output.ChannelUnit() = Input.ChannelUnit(); Output.ValueUnit().SetRawMin( Input.ValueUnit().RawMin() ) .SetRawMax( Input.ValueUnit().RawMax() ); float secsPerBlock = Parameter( "SampleBlockSize" ) / Parameter( "SamplingRate" ); Output.ElementUnit().SetOffset( 0 ).SetGain( secsPerBlock ).SetSymbol( "s" ); int visualizationTime = Output.ElementUnit().PhysicalToRaw( "15s" ); Output.ElementUnit().SetRawMin( 0 ).SetRawMax( visualizationTime - 1 ); }