/** * @brief MathFunctions::normalCDFInverse computes the inverse of the normal cumulative distribution function * @param p The value on which is applied the function * @return The inverse of the normal cumulative distribution function value */ double MathFunctions::normalCDFInverse(double p) { if (p <= 0.0 || p >= 1.0) { QString os; os = "Invalid input argument (" + QString::number(p) + "); must be larger than 0 but less than 1."; throw std::invalid_argument(os.toStdString().c_str()); } if (p < 0.5) { // F^-1(p) = - G^-1(p) return -rationalApproximation(qSqrt(-2.0*qLn(p))); } else { // F^-1(p) = G^-1(1-p) return rationalApproximation(qSqrt(-2.0*qLn(1-p))); } }
int maximallyFlat(double beta, double gamma, int *np, double *coefficient) { double a[LIMIT+1], c[LIMIT+1], betaMinimum, ac; int nt, numerator, n, ll, i; /* INITIALIZE NUMBER OF POINTS */ (*np) = 0; /* CUT-OFF FREQUENCY MUST BE BETWEEN 0 HZ AND NYQUIST */ if ((beta <= 0.0) || (beta >= 0.5)) return BETA_OUT_OF_RANGE; /* TRANSITION BAND MUST FIT WITH THE STOP BAND */ betaMinimum = ((2.0 * beta) < (1.0 - 2.0 * beta)) ? (2.0 * beta) : (1.0 - 2.0 * beta); if ((gamma <= 0.0) || (gamma >= betaMinimum)) return GAMMA_OUT_OF_RANGE; /* MAKE SURE TRANSITION BAND NOT TOO SMALL */ nt = (int)(1.0 / (4.0 * gamma * gamma)); if (nt > 160) return GAMMA_TOO_SMALL; /* CALCULATE THE RATIONAL APPROXIMATION TO THE CUT-OFF POINT */ ac = (1.0 + cos(TWO_PI * beta)) / 2.0; rationalApproximation(ac, &nt, &numerator, np); /* CALCULATE FILTER ORDER */ n = (2 * (*np)) - 1; if (numerator == 0) numerator = 1; /* COMPUTE MAGNITUDE AT NP POINTS */ c[1] = a[1] = 1.0; ll = nt - numerator; for (i = 2; i <= (*np); i++) { int j; double x, sum = 1.0, y; c[i] = cos(TWO_PI * ((double)(i-1)/(double)n)); x = (1.0 - c[i]) / 2.0; y = x; if (numerator == nt) continue; for (j = 1; j <= ll; j++) { double z = y; if (numerator != 1) { int jj; for (jj = 1; jj <= (numerator - 1); jj++) z *= 1.0 + ((double)j / (double)jj); } y *= x; sum += z; } a[i] = sum * pow((1.0 - x), numerator); } /* CALCULATE WEIGHTING COEFFICIENTS BY AN N-POINT IDFT */ for (i = 1; i <= (*np); i++) { int j; coefficient[i] = a[1] / 2.0; for (j = 2; j <= (*np); j++) { int m = ((i - 1) * (j - 1)) % n; if (m > nt) m = n - m; coefficient[i] += c[m+1] * a[j]; } coefficient[i] *= 2.0 / (double)n; } return 0; }