void RealFFT(const ColumnVector& U, ColumnVector& X, ColumnVector& Y) { // Fourier transform of a real series Tracer trace("RealFFT"); REPORT const int n = U.Nrows(); // length of arrays const int n2 = n / 2; if (n != 2 * n2) Throw(ProgramException("Vector length not multiple of 2", U)); ColumnVector A(n2), B(n2); Real* a = A.Store(); Real* b = B.Store(); Real* u = U.Store(); int i = n2; while (i--) { *a++ = *u++; *b++ = *u++; } FFT(A,B,A,B); int n21 = n2 + 1; X.ReSize(n21); Y.ReSize(n21); i = n2 - 1; a = A.Store(); b = B.Store(); // first els of A and B Real* an = a + i; Real* bn = b + i; // last els of A and B Real* x = X.Store(); Real* y = Y.Store(); // first els of X and Y Real* xn = x + n2; Real* yn = y + n2; // last els of X and Y *x++ = *a + *b; *y++ = 0.0; // first complex element *xn-- = *a++ - *b++; *yn-- = 0.0; // last complex element int j = -1; i = n2/2; while (i--) { Real c,s; cossin(j--,n,c,s); Real am = *a - *an; Real ap = *a++ + *an--; Real bm = *b - *bn; Real bp = *b++ + *bn--; Real samcbp = s * am + c * bp; Real sbpcam = s * bp - c * am; *x++ = 0.5 * ( ap + samcbp); *y++ = 0.5 * ( bm + sbpcam); *xn-- = 0.5 * ( ap - samcbp); *yn-- = 0.5 * (-bm + sbpcam); } }
void FFT(const ColumnVector& U, const ColumnVector& V, ColumnVector& X, ColumnVector& Y) { // from Carl de Boor (1980), Siam J Sci Stat Comput, 1 173-8 // but first try Sande and Gentleman Tracer trace("FFT"); REPORT const int n = U.Nrows(); // length of arrays if (n != V.Nrows() || n == 0) Throw(ProgramException("Vector lengths unequal or zero", U, V)); if (n == 1) { REPORT X = U; Y = V; return; } // see if we can use the newfft routine if (!FFT_Controller::OnlyOldFFT && FFT_Controller::CanFactor(n)) { REPORT X = U; Y = V; if ( FFT_Controller::ar_1d_ft(n,X.Store(),Y.Store()) ) return; } ColumnVector B = V; ColumnVector A = U; X.ReSize(n); Y.ReSize(n); const int nextmx = 8; #ifndef ATandT int prime[8] = { 2,3,5,7,11,13,17,19 }; #else int prime[8]; prime[0]=2; prime[1]=3; prime[2]=5; prime[3]=7; prime[4]=11; prime[5]=13; prime[6]=17; prime[7]=19; #endif int after = 1; int before = n; int next = 0; bool inzee = true; int now = 0; int b1; // initialised to keep gnu happy do { for (;;) { if (next < nextmx) { REPORT now = prime[next]; } b1 = before / now; if (b1 * now == before) { REPORT break; } next++; now += 2; } before = b1; if (inzee) { REPORT fftstep(A, B, X, Y, after, now, before); } else { REPORT fftstep(X, Y, A, B, after, now, before); } inzee = !inzee; after *= now; }
void RealFFTI(const ColumnVector& A, const ColumnVector& B, ColumnVector& U) { // inverse of a Fourier transform of a real series Tracer trace("RealFFTI"); REPORT const int n21 = A.Nrows(); // length of arrays if (n21 != B.Nrows() || n21 == 0) Throw(ProgramException("Vector lengths unequal or zero", A, B)); const int n2 = n21 - 1; const int n = 2 * n2; int i = n2 - 1; ColumnVector X(n2), Y(n2); Real* a = A.Store(); Real* b = B.Store(); // first els of A and B Real* an = a + n2; Real* bn = b + n2; // last els of A and B Real* x = X.Store(); Real* y = Y.Store(); // first els of X and Y Real* xn = x + i; Real* yn = y + i; // last els of X and Y Real hn = 0.5 / n2; *x++ = hn * (*a + *an); *y++ = - hn * (*a - *an); a++; an--; b++; bn--; int j = -1; i = n2/2; while (i--) { Real c,s; cossin(j--,n,c,s); Real am = *a - *an; Real ap = *a++ + *an--; Real bm = *b - *bn; Real bp = *b++ + *bn--; Real samcbp = s * am - c * bp; Real sbpcam = s * bp + c * am; *x++ = hn * ( ap + samcbp); *y++ = - hn * ( bm + sbpcam); *xn-- = hn * ( ap - samcbp); *yn-- = - hn * (-bm + sbpcam); } FFT(X,Y,X,Y); // have done inverting elsewhere U.ReSize(n); i = n2; x = X.Store(); y = Y.Store(); Real* u = U.Store(); while (i--) { *u++ = *x++; *u++ = - *y++; } }
//Predict on a chunk of data. ReturnMatrix SOGP::predictM(const Matrix& in, ColumnVector &sigconf,bool conf){ //printf("SOGP::Predicting on %d points\n",in.Ncols()); Matrix out(alpha.Ncols(),in.Ncols()); sigconf.ReSize(in.Ncols()); for(int c=1;c<=in.Ncols();c++) out.Column(c) = predict(in.Column(c),sigconf(c),conf); out.Release(); return out; }
static void SlowFT(const ColumnVector& a, const ColumnVector&b, ColumnVector& x, ColumnVector& y) { int n = a.Nrows(); x.ReSize(n); y.ReSize(n); Real f = 6.2831853071795864769/n; for (int j=1; j<=n; j++) { Real sumx = 0.0; Real sumy = 0.0; for (int k=1; k<=n; k++) { Real theta = - (j-1) * (k-1) * f; Real c = cos(theta); Real s = sin(theta); sumx += c * a(k) - s * b(k); sumy += s * a(k) + c * b(k); } x(j) = sumx; y(j) = sumy; } }
static void SlowDTT_II(const ColumnVector& a, ColumnVector& c, ColumnVector& s) { int n = a.Nrows(); c.ReSize(n); s.ReSize(n); Real f = 6.2831853071795864769 / (4*n); int k; for (k=1; k<=n; k++) { Real sum = 0.0; const int k1 = k-1; // otherwise Visual C++ 5 fails for (int j=1; j<=n; j++) sum += cos(k1 * (2*j-1) * f) * a(j); c(k) = sum; } for (k=1; k<=n; k++) { Real sum = 0.0; for (int j=1; j<=n; j++) sum += sin(k * (2*j-1) * f) * a(j); s(k) = sum; } }
static void SlowDTT(const ColumnVector& a, ColumnVector& c, ColumnVector& s) { int n1 = a.Nrows(); int n = n1 - 1; c.ReSize(n1); s.ReSize(n1); Real f = 6.2831853071795864769 / (2*n); int k; int sign = 1; for (k=1; k<=n1; k++) { Real sum = 0.0; for (int j=2; j<=n; j++) sum += cos((j-1) * (k-1) * f) * a(j); c(k) = sum + (a(1) + sign * a(n1)) / 2.0; sign = -sign; } for (k=2; k<=n; k++) { Real sum = 0.0; for (int j=2; j<=n; j++) sum += sin((j-1) * (k-1) * f) * a(j); s(k) = sum; } s(1) = s(n1) = 0; }
//Predict the output and uncertainty for this input. ReturnMatrix SOGP::predict(const ColumnVector& in, double &sigma,bool conf){ double kstar = m_params.m_kernel->kstar(in); ColumnVector k=m_params.m_kernel->kernelM(in,BV); ColumnVector out; if(current_size==0){ sigma = kstar+m_params.s20; //We don't actually know the correct output dimensionality //So return nothing. out.ReSize(0); } else{ out=(k.t()*alpha).t();//Page 33 sigma=m_params.s20 + kstar + (k.t()*C*k).AsScalar();//Ibid..needs s2 from page 19 } if(sigma<0){//Numerical instability? printf("SOGP:: sigma (%lf) < 0!\n",sigma); sigma=0; } //Switch to a confidence (0-100) if(conf){ //Normalize to one sigma /= kstar+m_params.s20; //switch diretion sigma = 1-sigma; //and times 100; sigma *=100; //sigma = (1-sigma)*100; } else sigma=sqrt(sigma); out.Release(); return out; }
bool SpectClust::MaxEigen(const Matrix &M, double &maxValue, ColumnVector &MaxVec, int maxIterations) { double maxDelta = 1e-6; bool converged = false; int i = 0; int nRows = M.Ncols(); if(M.Ncols() != M.Nrows()) Err::errAbort("MaxEigen() - Can't get eigen values of non square matrices."); if(M.Ncols() <= 0) Err::errAbort("MaxEigen() - Must have positive number of rows and columns."); ColumnVector V(M.Ncols()); V = 1.0 / M.Nrows(); // any vector really... V = V / Norm1(V); MaxVec.ReSize(M.Ncols()); for(i = 0; i < maxIterations; ++i) { // MaxVec = M * V; multByMatrix(MaxVec, V, M); double delta = 0; double norm = sqrt(SumSquare(MaxVec)); for(int vIx = 0; vIx < nRows; vIx++) { MaxVec.element(vIx) = MaxVec.element(vIx) / norm; // scale so we don't get too big. } for(int rowIx = 0; rowIx < nRows; rowIx++) { delta += fabs((double)MaxVec.element(rowIx) - V.element(rowIx)); } if(delta < maxDelta) break; // we've already converged to eigen vector. V = MaxVec; } if(i < maxIterations) { converged = true; } // calculate approximate max eigen value using Rayleigh quotient (x'*M*x/x'*x). Matrix num = (MaxVec.t() * M * MaxVec); Matrix denom = (MaxVec.t() * MaxVec); maxValue = num.element(0,0) / denom.element(0,0); return converged; }