123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- /**
- * @file TraceApproximation.cpp
- * @brief approximation of the trace term within the gp regression gradient
- * @author Erik Rodner
- * @date 01/29/2010
- */
- #include <iostream>
- #include "TraceApproximation.h"
- using namespace std;
- using namespace NICE;
- using namespace OBJREC;
- TraceApproximation::TraceApproximation( const Config *conf, const string & section )
- {
- numTraceSamples = conf->gI(section, "num_trace_samples", 100 );
- displayPoints = conf->gI(section, "display_points", 100 );
- if ( displayPoints > numTraceSamples )
- displayPoints = numTraceSamples;
- }
- TraceApproximation::~TraceApproximation()
- {
- }
- void TraceApproximation::preSampling ( const KernelData *kernelData, Matrix & samples, Matrix & samplesPreMultiplied ) const
- {
- if ( numTraceSamples == 0 ) return;
- uint kernelSize = kernelData->getKernelMatrixSize();
- samples.resize ( kernelSize, numTraceSamples );
- samplesPreMultiplied.resize ( kernelSize, numTraceSamples );
- cerr << "TraceApproximation: number of samples " << numTraceSamples << endl;
- cerr << "TraceApproximation: pre-sampling " << endl;
- for ( uint i = 0 ; i < kernelSize ; i++ )
- for ( uint k = 0 ; (int)k < numTraceSamples ; k++ )
- samples(i,k) = randGaussDouble ( 1.0 );
- cerr << "TraceApproximation: pre-multiplication ";
- for ( uint k = 0 ; (int)k < numTraceSamples; k++ )
- {
- if ( k % (numTraceSamples/displayPoints) == 0 )
- {
- cerr << ".";
- cerr.flush();
- }
- Vector rinv = samplesPreMultiplied.getColumnRef ( k );
- kernelData->computeInverseKernelMultiply ( samples.getColumn(k), rinv );
- }
- cerr << endl;
- }
- double TraceApproximation::getApproximateTraceTerm ( const KernelData *kernelData, const Matrix & jacobiMatrix ) const
- {
- if ( numTraceSamples == 0 ) return 0.0;
- Vector r ( jacobiMatrix.rows() );
- Vector rinv;
- Vector rJacobi;
- double trace_approx = 0.0;
- double trace_approx_old = 0.0;
- double stddev = 0.0;
- cerr << "TraceApproximation: number of samples " << numTraceSamples << endl;
- cerr << "TraceApproximation: sampling ";
- for ( uint k = 0 ; (int)k < numTraceSamples; k++ )
- {
- if ( k % (numTraceSamples/displayPoints) == 0 )
- {
- cerr << ".";
- cerr.flush();
- }
- // normality is not required ? (says wikipedia)
- // but seems to yield "better results"
- r = Vector::GaussRandom ( r.size(), 0.0, 1.0 );
- kernelData->computeInverseKernelMultiply ( r, rinv );
- rJacobi = jacobiMatrix * r;
- rJacobi = r;
- double tau = rinv.scalarProduct ( rJacobi );
- // idea of RunningStat
- trace_approx = trace_approx + (tau - trace_approx) / (k+1);
- stddev += ( tau - trace_approx_old ) * ( tau - trace_approx );
- trace_approx_old = trace_approx;
- }
- cerr << endl;
- stddev /= (numTraceSamples-1);
- stddev = sqrt(stddev);
- double standard_error = stddev / sqrt((double)numTraceSamples);
- double rel_standard_error = standard_error / fabs(trace_approx);
- cerr << "TraceApproximation: relative error " << rel_standard_error << endl;
- return trace_approx;
- }
- double TraceApproximation::getApproximateTraceTermKronecker ( const KernelData *kernelData, const Matrix & A, const Matrix & B ) const
- {
- if ( numTraceSamples == 0 ) return 0.0;
- Vector r ( A.rows() * B.rows() );
- Vector rinv;
- Vector rJacobi;
- double trace_approx = 0.0;
- double trace_approx_old = 0.0;
- double stddev = 0.0;
- cerr << "TraceApproximation: number of samples " << numTraceSamples << endl;
- cerr << "TraceApproximation: sampling ";
- for ( uint k = 0 ; (int)k < numTraceSamples; k++ )
- {
- if ( k % (numTraceSamples/displayPoints) == 0 )
- {
- cerr << ".";
- cerr.flush();
- }
- // normality is not required ? (says wikipedia)
- // but seems to yield "better results"
- r = Vector::GaussRandom ( r.size(), 0.0, 1.0 );
- kernelData->computeInverseKernelMultiply ( r, rinv );
- // this is the only difference -----------------------
- kroneckerProductMultiplication ( A, B, r, rJacobi );
- double tau = rinv.scalarProduct ( rJacobi );
- // idea of RunningStat
- trace_approx = trace_approx + (tau - trace_approx) / (k+1);
- stddev += ( tau - trace_approx_old ) * ( tau - trace_approx );
- trace_approx_old = trace_approx;
- }
- cerr << endl;
- stddev /= (numTraceSamples-1);
- stddev = sqrt(stddev);
- double standard_error = stddev / sqrt((double)numTraceSamples);
- double rel_standard_error = standard_error / fabs(trace_approx);
- cerr << "TraceApproximation: relative error " << rel_standard_error << endl;
- return trace_approx;
- }
- double TraceApproximation::getApproxTraceTermKroneckerPre ( Matrix & samples, Matrix & samplesPreMultiplied, const Matrix & A, const Matrix & B ) const
- {
- if ( numTraceSamples == 0 ) return 0.0;
- double trace_approx = 0.0;
- double trace_approx_old = 0.0;
- double stddev = 0.0;
- Vector rJacobi;
- cerr << "TraceApproximation: estimating ";
- for ( uint k = 0 ; (int)k < numTraceSamples; k++ )
- {
- if ( k % (numTraceSamples/displayPoints) == 0 )
- {
- cerr << ".";
- cerr.flush();
- }
- // this is the only difference -----------------------
- Vector r = samples.getColumnRef(k);
- Vector rinv = samplesPreMultiplied.getColumnRef(k);
- kroneckerProductMultiplication ( A, B, r, rJacobi );
- double tau = rinv.scalarProduct ( rJacobi );
- // idea of RunningStat
- trace_approx = trace_approx + (tau - trace_approx) / (k+1);
- stddev += ( tau - trace_approx_old ) * ( tau - trace_approx );
- trace_approx_old = trace_approx;
- }
- cerr << endl;
- stddev /= (numTraceSamples-1);
- stddev = sqrt(stddev);
- double standard_error = stddev / sqrt( (double)numTraceSamples);
- double rel_standard_error = standard_error / fabs(trace_approx);
- cerr << "TraceApproximation: relative error " << rel_standard_error << endl;
- return trace_approx;
- }
|