/* TransferFunction.java created 2010-11-30
*
*/
package org.signalml.math.iirdesigner;
import org.apache.commons.math.complex.Complex;
import org.signalml.math.ArrayOperations;
import org.signalml.math.iirdesigner.math.ComplexPolynomial;
/**
* This class represents a complex frequency response of a filter. Contains two
* arrays - one of them holds the frequencies at which the frequency response
* was computed (from 0 to PI), the other one holds the frequency response for
* those frequencies (each number is a complex number).
* @author Piotr Szachewicz
*/
public class TransferFunction {
/**
* The coefficients of the filter for which this transfer function
* is calculated.
*/
protected FilterCoefficients filterCoefficients;
/**
* an array of frequencies at which the frequency response was computed
*/
protected double[] frequencies;
/**
* an array holding the complex frequency response
*/
protected Complex[] gain;
/**
* Constructor. Creates an empty {@link TransferFunction} which can
* contain specified number of points.
*
* @param numberOfPoints number of frequencies at which the frequency response
* will be computed
*/
public TransferFunction(int numberOfPoints, FilterCoefficients filterCoefficients) {
frequencies = new double[numberOfPoints];
gain = new Complex[numberOfPoints];
this.filterCoefficients = filterCoefficients;
calculateTransferFunction();
}
/**
* Calculates the {@link TransferFunction complex frequency response}
* for the parameters given to to the constructor.
*/
protected void calculateTransferFunction() {
double[] numeratorCoefficients = ArrayOperations.reverse(filterCoefficients.getBCoefficients());
double[] denominatorCoefficients = ArrayOperations.reverse(filterCoefficients.getACoefficients());
ComplexPolynomial numerator = new ComplexPolynomial(numeratorCoefficients);
ComplexPolynomial denominator = new ComplexPolynomial(denominatorCoefficients);
double frequency;
Complex exponent;
for (int i = 0; i < frequencies.length; i++) {
frequency = i * Math.PI / frequencies.length;
exponent = (new Complex(0, -frequency)).exp();
Complex numeratorValue = numerator.evaluate(exponent);
Complex denominatorValue = denominator.evaluate(exponent);
Complex value = numeratorValue.divide(denominatorValue);
setValue(i, frequency, value);
}
}
/**
* Sets the value for the specified elements in the frequency and
* gain arrays.
*
* @param i the index of the element to change
* @param frequency the new value of frequency to be put in the array
* @param value the new value of gain to be put in the array
*/
protected void setValue(int i, double frequency, Complex value) {
frequencies[i] = frequency;
gain[i] = value;
}
/**
* Returns how much points this frequency response holds
*
* @return the number of points this frequency response holds.
*/
public int getSize() {
if (frequencies != null)
return frequencies.length;
return 0;
}
/**
* Returns an array containing the frequencies at which this
* frequency response was calculated.
*
* @return an array of frequencies
*/
public double[] getFrequencies() {
return frequencies;
}
/**
* Returns the specified element of the frequency array.
*
* @param number the index of the element to be returned
* @return the specified element of the frequency array
*/
public double getFrequency(int number) {
return frequencies[number];
}
/**
* Returns an array containing the frequency response.
*
* @return the frequency response
*/
public Complex[] getGain() {
return gain;
}
/**
* Returns the specified element of the gain array.
*
* @param number the index of the element to be returned
* @return the specified element of the gain array
*/
public Complex getGain(int number) {
return gain[number];
}
}