static void ao_vdivs(vec *c, vec v, double n) { vDSP_vsdivD(v.co, 1, &n, c->co, 1, 3); /* c->x = v.x / n; c->y = v.y / n; c->z = v.z / n; */ }
void AVFEqualizerBand::SetupHighShelfFilter(double omega, double bw, double gain) { double egm = gain - 1.0; double egp = gain + 1.0; double alpha = tan(bw / 2.0); double delta = 2.0 * sqrt(gain) * alpha; double cosF = cos(omega); mCoefficients[IND_A0] = (egp + egm * cosF + delta) * gain; mCoefficients[IND_A1] = (egm + egp * cosF) * -2.0 * gain; mCoefficients[IND_A2] = (egp + egm * cosF - delta) * gain; double b0 = egp - egm * cosF + delta; mCoefficients[IND_B1] = (egm - egp * cosF) * 2.0; mCoefficients[IND_B2] = egp - egm * cosF - delta; // pre-scale coefficients vDSP_vsdivD(mCoefficients, 1, &b0, mCoefficients, 1, 5); }
/* * vDSP_deq22: * https://developer.apple.com/library/mac/documentation/Accelerate/Reference/vDSPRef/Reference/reference.html#//apple_ref/c/func/vDSP_deq22 * * The biquadratic filter equation for the nth sample is: * D[n] = S[n] * a0 + S[n-1] * a1 + S[n-2] * a2 - D[n-1] * b1 - D[n-2] * b2 * * vDSP_deq22 stuffs all coefficients in vector B and uses: * for p in [0,2]: * A(n-p)i * B(p) -> A(n)*B[0] + A(n-1)*B[1] + A(n-2)*B[2] * * for p in [3,4]: * C(n-p+2)k * B(p) -> C(n-1)*B[3] + C(n-2)*B[4] * * where A and C are vectors of at least size N+2 * so B[0..2] is a0 to a2 respectively and B[3..4] is b1 and b2 respectively * * The formulae used to calculate the coefficients are taken from GStreamer so * we can match the behavior of the GStreamer pipeline (and they work well enough) * though modified for SIMD operations using vDSP_deq22. * * Note that the GStreamer coefficient names (a0-a2,b0-b2) are swapped from other * examples, but the use is the same. */ void AVFEqualizerBand::SetupPeakFilter(double omega, double bw, double gain) { double cosF = cos(omega); double alpha = tan(bw / 2.0); double alpha1 = alpha * gain; double alpha2 = alpha / gain; // set up peak filter coefficients mCoefficients[IND_A0] = 1.0 + alpha1; mCoefficients[IND_A1] = -2.0 * cosF; mCoefficients[IND_A2] = 1.0 - alpha1; double b0 = 1.0 + alpha2; mCoefficients[IND_B1] = -2.0 * cosF; mCoefficients[IND_B2] = 1.0 - alpha2; // pre-scale coefficients vDSP_vsdivD(mCoefficients, 1, &b0, mCoefficients, 1, 5); }
int xtract_autocorrelation_fft(const double *data, const int N, const void *argv, double *result) { double *rfft = NULL; int n = 0; int M = 0; #ifndef USE_OOURA DSPDoubleSplitComplex *fft = NULL; double M_double = 0.0; #endif M = N << 1; /* Zero pad the input vector */ rfft = (double *)calloc(M, sizeof(double)); memcpy(rfft, data, N * sizeof(double)); #ifdef USE_OOURA rdft(M, 1, rfft, ooura_data_autocorrelation_fft.ooura_ip, ooura_data_autocorrelation_fft.ooura_w); for(n = 2; n < M; ++n) { rfft[n*2] = XTRACT_SQ(rfft[n*2]) + XTRACT_SQ(rfft[n*2+1]); rfft[n*2+1] = 0.0; } rfft[0] = XTRACT_SQ(rfft[0]); rfft[1] = XTRACT_SQ(rfft[1]); rdft(M, -1, rfft, ooura_data_autocorrelation_fft.ooura_ip, ooura_data_autocorrelation_fft.ooura_w); #else /* vDSP has its own autocorrelation function, but it doesn't fit the * LibXtract model, e.g. we can't guarantee it's going to use * an FFT for all values of N */ fft = &vdsp_data_autocorrelation_fft.fft; vDSP_ctozD((DSPDoubleComplex *)data, 2, fft, 1, N); vDSP_fft_zripD(vdsp_data_autocorrelation_fft.setup, fft, 1, vdsp_data_autocorrelation_fft.log2N, FFT_FORWARD); for(n = 0; n < N; ++n) { fft->realp[n] = XTRACT_SQ(fft->realp[n]) + XTRACT_SQ(fft->imagp[n]); fft->imagp[n] = 0.0; } vDSP_fft_zripD(vdsp_data_autocorrelation_fft.setup, fft, 1, vdsp_data_autocorrelation_fft.log2N, FFT_INVERSE); #endif /* Normalisation factor */ M = M * N; #ifdef USE_OOURA for(n = 0; n < N; n++) result[n] = rfft[n] / (double)M; free(rfft); #else M_double = (double)M; vDSP_ztocD(fft, 1, (DOUBLE_COMPLEX *)result, 2, N); vDSP_vsdivD(result, 1, &M_double, result, 1, N); #endif return XTRACT_SUCCESS; }
/* Q: problem data, 1-dim array of length n*n * wneg: slope of negative part, 1-dim array of length n * wpos: slope of positive part, 1-dim array of length n * sigma: initial penalty parameter * maxIter: max number of iterations * d: initial feasible vector d, 1-dim array of length n * iter_arr, obj_arr and time_arr are output variables, CURRENTLY NOT USED!!! */ int CDlogdet_nonsmooth(int n, double* Q, double* wneg, double* wpos, double sigma, int maxIter, double* d, double* Vinit, int* iter_arr, double* obj_arr, double* time_arr) { int iter = 0; int k = 0; double Vkk = 0; double dk = 0; double dchange = 0; clock_t iterTimer = 0; double GRAD_TOL = 3E-2; double MIN_TAU = 1E-5; double TERM_PROG = 1E-4; double relgrad = 1E17; double tmpScalar1 = 0; double VERYSMALLNUM = 1E-9; double obj = 0; double prevobj = 1E17; double nrmW = 0; double TAU_UPDATE = 0.8; int nsq = n*n; vDSP_Length tmpPosition = 0; double* V = NULL; double* vk = NULL; double* tmpVec1 = NULL; double* tmpVec2 = NULL; double* tmpVec3 = NULL; double* tmpVec4 = NULL; double* tmpVec5 = NULL; double* tmpVec6 = NULL; double* subg = NULL; V = (double*) malloc(nsq*sizeof(double)); vk = (double*) malloc(n*sizeof(double)); subg = (double*) malloc(n*sizeof(double)); tmpVec1 = (double*) malloc(n*sizeof(double)); tmpVec2 = (double*) malloc(n*sizeof(double)); tmpVec3 = (double*) malloc(n*sizeof(double)); tmpVec4 = (double*) malloc(n*sizeof(double)); tmpVec5 = (double*) malloc(n*sizeof(double)); tmpVec6 = (double*) malloc(n*sizeof(double)); char UPLO = 'L'; int LDA = n; int INFO = 0; if (PRINTLEVEL) { PRINT("Entering CDlogdet_nonsmooth: n=%d, sigma=%f, maxIter=%d\n",n,sigma,maxIter); } iterTimer = clock(); /*Compute V = inv(Q+d), only stores the lower triangular part*/ if (NULL==Vinit) { cblas_dcopy(nsq, Q, 1, V, 1); cblas_daxpy(n, 1, d, 1, V, n+1); UPLO = 'L'; LDA = n; INFO = 0; dpotrf_(&UPLO, &n, V, &LDA, &INFO); dpotri_(&UPLO, &n, V, &LDA, &INFO); } else { cblas_dcopy(nsq, Vinit, 1, V, 1); } //printMat(V,n); //printMat(Vinit,n); nrmW = MAX(cblas_dnrm2(n, wneg, 1), cblas_dnrm2(n, wpos, 1)); vDSP_vmulD(wneg,1,d,1,tmpVec1,1,n); vDSP_vmulD(wpos,1,d,1,tmpVec2,1,n); vDSP_vmaxD(tmpVec1, 1, tmpVec2, 1, tmpVec3, 1, n); vDSP_sveD(tmpVec3,1,&prevobj,n); while(iter<maxIter) { /*Compute sub-gradient*/ /*tmpVec1 <= wneg*/ cblas_dcopy(n, wneg, 1, tmpVec1, 1); /*tmpVec1 <= wneg-sigma*diag(V)*/ cblas_daxpy(n, -sigma, V, n+1, tmpVec1,1); /*tmpVec2 <= wpos*/ cblas_dcopy(n, wpos, 1, tmpVec2, 1); /*tmpVec2 <= wpos-sigma*diag(V)*/ cblas_daxpy(n, -sigma, V, n+1, tmpVec2,1); /*tmpVec3 <= max(0,wneg-sigma*diag(V)) */ tmpScalar1 = 0; vDSP_vthresD(tmpVec1,1,&tmpScalar1,tmpVec3,1,n); /*tmpVec4 <= -min(0,wpos-sigma*diag(V))*/ vDSP_vnegD(tmpVec2,1,tmpVec4,1,n); tmpScalar1 = 0; vDSP_vthresD(tmpVec4,1,&tmpScalar1,tmpVec4,1,n); /*tmpVec3 <= max(0,wneg-sigma*diag(V)) + min(0,wpos-sigma*diag(V))*/ cblas_daxpy(n,-1,tmpVec4,1,tmpVec3,1); /*If d<0, use wneg-sigma*diag(V)*/ /*tmpVec4_i = 1 <==> d_i < -VERYSMALLNUM */ /*tmpVec4 <= (-d)*/ vDSP_vnegD(d,1,tmpVec4,1,n); tmpScalar1 = 1; vDSP_vlimD(tmpVec4,1, &VERYSMALLNUM, &tmpScalar1,tmpVec4,1,n); tmpScalar1 = 1; vDSP_vsaddD(tmpVec4,1,&tmpScalar1, tmpVec4, 1, n); tmpScalar1 = 2; vDSP_vsdivD(tmpVec4,1,&tmpScalar1, tmpVec4, 1, n); /*tmpVec5[i] = 1 <==> d_i > VERYSMALLNUM*/ cblas_dcopy(n,d,1,tmpVec5,1); tmpScalar1 = 1; vDSP_vlimD(tmpVec5, 1, &VERYSMALLNUM, &tmpScalar1, tmpVec5, 1, n); tmpScalar1 = 1; vDSP_vsaddD(tmpVec5, 1, &tmpScalar1, tmpVec5, 1, n); tmpScalar1 = 2; vDSP_vsdivD(tmpVec5,1,&tmpScalar1, tmpVec5, 1, n); /*tmpVec6[i] = 1 <==> abs(d_i) < VERYSMALLNUM*/ vDSP_vaddD(tmpVec4, 1, tmpVec5, 1, tmpVec6, 1, n); tmpScalar1 = -1; vDSP_vsaddD(tmpVec6,1, &tmpScalar1, tmpVec6, 1, n); vDSP_vnegD(tmpVec6,1,tmpVec6,1,n); /*Multiply, Multiply, Multiply, then add */ vDSP_vmmaD(tmpVec1, 1, tmpVec4, 1, tmpVec2, 1, tmpVec5, 1, subg,1, n); vDSP_vmaD(tmpVec3, 1, tmpVec6, 1, subg, 1, subg, 1, n); /*Choose the index with largest abs(subg)*/ vDSP_maxmgviD(subg,1,&tmpScalar1,&tmpPosition,n); /*k is the selected index*/ k = (int) tmpPosition; Vkk = V[k*n+k]; dk = d[k]; if (1-dk*Vkk<=0 || (sigma*Vkk/(1-dk*Vkk)>wpos[k]) ) { dchange = sigma/wpos[k] - 1/Vkk; } else if(sigma*Vkk/(1-dk*Vkk)<wneg[k]) { dchange = sigma/wneg[k] - 1/Vkk; } else { dchange = -dk; } d[k] += dchange; cblas_dcopy(k+1, &V[k], n, vk, 1); cblas_dcopy(n-k-1, &V[k*n+k+1], 1, &vk[k+1], 1); tmpScalar1 = -(dchange/(1+dchange*Vkk)); cblas_dsyr(CblasColMajor, CblasLower, n, tmpScalar1, vk, 1, V, n); iter ++; relgrad = cblas_dnrm2(n,subg,1)/nrmW; vDSP_vmulD(wneg,1,d,1,tmpVec1,1,n); vDSP_vmulD(wpos,1,d,1,tmpVec2,1,n); vDSP_vmaxD(tmpVec1, 1, tmpVec2, 1, tmpVec3, 1, n); vDSP_sveD(tmpVec3,1,&obj,n); if (relgrad<GRAD_TOL) { sigma = MAX(MIN_TAU, sigma*TAU_UPDATE); if (PRINTLEVEL) { PRINT("Iter = %5d, sig=%1.2e(#) , obj = %1.5e, relgrad = %1.3f\n", iter, sigma, obj, relgrad); } } else if (iter==1 || iter%n==0) { if (PRINTLEVEL) { PRINT("Iter = %5d, sig=%1.2e , obj = %1.5e, relgrad = %1.3f, t=%0.3f\n", iter, sigma, obj, relgrad,((double)(clock()-iterTimer))/CLOCKS_PER_SEC); } } if (iter%n==0) { if (obj<prevobj && ABS(prevobj-obj)<TERM_PROG*ABS(obj)) { if(PRINTLEVEL) { PRINT("Terminate due to small progress.\n"); } break; } else { prevobj = obj; } } } free(V); free(vk); free(tmpVec1); free(tmpVec2); free(tmpVec3); free(tmpVec4); free(tmpVec5); free(tmpVec6); free(subg); return 0; }