/// <summary> /// コンストラクタ(フィルタ係数をセット) /// </summary> /// <param name="coeff">フィルタ係数</param> public Filtering(FilterCoefficient coeff) { Coeff = coeff; }
/// <summary> /// 双一次変換 /// </summary> /// <param name="order">フィルタ次数</param> /// <param name="Wa">フィルタの正規化カットオフ周波数または中心周波数(ナイキスト周波数で正規化)</param> /// <param name="aAnalog">アナログフィルタの分子の係数</param> /// <param name="bAnalog">アナログフィルタの分母の係数</param> /// <param name="filterType">フィルタの種類 FilterTypeで選択</param> /// <returns>FilterCoefficient 双一次変換されたデジタルフィルタの係数</returns> private static FilterCoefficient BilinearTransform(int order, double Wa, double[,] aAnalog, double[,] bAnalog, FilterType filterType) { // 双一次変換の格納用配列 var a = new double[aAnalog.GetLength(0), aAnalog.GetLength(1)]; var b = new double[bAnalog.GetLength(0), bAnalog.GetLength(1)]; //フィルタの次数の偶数奇数判定 bool odd = order % 2 != 0; // セクション数 int sections = aAnalog.GetLength(0); // 双一次変換の変換係数 double h = 1 / (Wa * Math.PI / 2); for (var k = 0; k < sections; k++) { double BB; if (k == 0 && odd && (filterType == FilterType.Low || filterType == FilterType.High)) { //ローパスハイパスの奇数一次のみ、1次のセクションとなる // 分母の 係数b0の逆数 BB = 1 / (h + bAnalog[0, 0]); a[k, 0] = BB * (aAnalog[0, 1] * h + aAnalog[0, 0]); a[k, 1] = BB * (-aAnalog[0, 1] * h + aAnalog[0, 0]); a[k, 2] = 0; b[k, 0] = BB * (h + bAnalog[0, 0]); b[k, 1] = BB * (-h + bAnalog[0, 0]); b[k, 2] = 0; } else { // 分母の 係数b0の逆数 BB = 1 / (h * h + bAnalog[k, 1] * h + bAnalog[k, 2]); a[k, 0] = BB * (aAnalog[k, 2] * h * h + aAnalog[k, 1] * h + aAnalog[k, 0]); a[k, 1] = BB * 2 * (-aAnalog[k, 2] * h * h + aAnalog[k, 0]); a[k, 2] = BB * (aAnalog[k, 2] * h * h - aAnalog[k, 1] * h + aAnalog[k, 0]); b[k, 0] = BB * (h * h + bAnalog[k, 1] * h + bAnalog[k, 2]); b[k, 1] = BB * (-2 * h * h + 2 * bAnalog[k, 2]); b[k, 2] = BB * (h * h - bAnalog[k, 1] * h + bAnalog[k, 2]); } } //ゲインを最初のセクションに集める double gain = 1; for (var k = 0; k < sections; k++) { gain *= a[k, 0]; a[k, 2] /= a[k, 0]; a[k, 1] /= a[k, 0]; a[k, 0] /= a[k, 0]; } a[0, 0] *= gain; a[0, 1] *= gain; a[0, 2] *= gain; var filterValue = new FilterCoefficient(); filterValue.Numerator = a; filterValue.Denominator = b; filterValue.Sections = sections; filterValue.Order = order; return(filterValue); }