- [tpcode]
- // Purpose
- // A program to demonstrate the application of a simple digital filter
- //
- // Overview
- // A sequence of data items and digital filter values need to be entered by the
- // user. The application of the filter to the data involves a simple convolution
- // operation. The filtered data are stored separately.
- //
- // Example
- // before filtering:
- // data_in = [0 1 3 6 3 1 0]
- // filter = [-0.5 1 -0.5]
- // after filtering:
- // data_out = [-0.5 -0.5 3 -0.5 -0.5]
- // where
- // data_out[0]=data_in[0]*filter[0]+data_in[1]*filter[1]+data_in[2]*filter[2]
- // data_out[1]=data_in[1]*filter[0]+data_in[2]*filter[1]+data_in[3]*filter[2]
- // data_out[2]=data_in[2]*filter[0]+data_in[3]*filter[1]+data_in[4]*filter[2]
- // data_out[3]=data_in[3]*filter[0]+data_in[4]*filter[1]+data_in[5]*filter[2]
- // data_out[4]=data_in[4]*filter[0]+data_in[5]*filter[1]+data_in[6]*filter[2]
- //
- // The program checks the following
- // 1.The data and filter values must have been entered before the filter is
- // applied
- // 2.The filter is not applied if the number of filter values is greater than
- // the number of input data values
- // 3.The data and filter values must have been entered and the filter applied
- // before the filtered data can be displayed
- #include <iostream>
- using namespace std;
-
- // the data values and the filter
- struct TheFilter {
- double* Values; // the filter values POINTER
- unsigned long Length; // number of filter values
- bool Valid; // true if the filter values have been obtained
- };
-
- struct TheData {
- double* Values; // holds the data to be filtered POINTER
- unsigned long Length; // number of data values
- bool Valid; // true if the data values have been obtained
- };
-
- // function return values
- enum { OK, FILTER_TOO_LONG };
-
- // function prototypes
-
- void EnterData(TheData &OriginalData); //Function Prototypes
- void EnterFilter(TheFilter &Filter);
- int ApplyFilter(TheFilter &Filter, TheData &OriginalData, TheData &FilteredData);
- void DisplayData(TheFilter &Filter, TheData &OriginalData, TheData &FilteredData);
-
- // Control the principal operations of the program
- // Arguments: None
- // Returns: 0 on completion
- int main()
- {
- // define the filter and its initial values
- TheFilter Filter = { 0,0,false };
-
- // define the original data and its initial values
- TheData OriginalData = { 0,0,false };
-
- // define the filtered data and its initial values
- TheData FilteredData = { 0,0,false };
-
- char UserInput;
-
- // loop until the user wishes to exit
- while (1) {
-
- // show the menu of options
- cout << endl;
- cout << "Filter Menu" << endl;
- cout << "-----------" << endl;
- cout << "1. Enter data for filtering" << endl;
- cout << "2. Enter filter values" << endl;
- cout << "3. Apply filter" << endl;
- cout << "4. Display filtered data" << endl;
- cout << "5. Exit from the program" << endl << endl;
-
- // get the user's choice
- cout << "Enter your option: ";
- cin >> UserInput;
- cout << endl;
-
- // act on the user's input
- switch (UserInput) {
- case '1':
- EnterData(OriginalData);
- FilteredData.Valid = false;
- break;
-
- case '2':
- EnterFilter(Filter);
- FilteredData.Valid = false;
- break;
-
- case '3':
- if (Filter.Valid == true && OriginalData.Valid == true && FilteredData.Valid == false) {
- if (ApplyFilter(Filter, OriginalData, FilteredData) == FILTER_TOO_LONG) {
- cout << "The filter must not be longer than the data" << endl;
- }
- else {
- FilteredData.Valid = true;
- cout << "Filter applied" << endl;
- }
- }
- break;
-
- case '4':
- if (Filter.Valid == true && OriginalData.Valid == true && FilteredData.Valid == true) {
- DisplayData(Filter, OriginalData, FilteredData);
- }
- else {
- cout << "Data have not yet been filtered" << endl;
- }
- break;
-
- case '5':
- delete[] Filter.Values;
- delete[] OriginalData.Values;
- delete[] FilteredData.Values;
- return 0;
- break;
-
- default:
- cout << "Invalid entry" << endl << endl;
- break;
- }
- }
- }
-
- // Allow the user to enter the data to be filtered 1 EnterData
- // Arguments:
- // (1) the structure containing the input data
- // Returns: nothing
- //
- void EnterData(TheData &OriginalData)
- {
- // initialize the data structure that holds the data to be filtered, including getting
- delete[] OriginalData.Values;
- // the number of data values from the user
- cout << "Please enter the number of data values would you like to convolute?" << endl;
- cin >> OriginalData.Length;
-
- // allocate memory to the data
- // Obtain memory from free store for the array
- OriginalData.Values = new double[OriginalData.Length];
- if (OriginalData.Values == 0)
- {
- cerr << "\n*** Unable to allocate memory *** \n";
- exit(1);
- }
- else
- {
- // obtain all of the data values
- for (unsigned int i = 0; i < (OriginalData.Length); i++)
- {
- cout << "Enter data value " << i + 1 << ":" << endl;
- cin >> *(OriginalData.Values + i);
- }
- }
- cout << "Data Assigned" << endl;
-
- OriginalData.Valid = true;
-
- }
-
- // Allow the user to enter the filter values
- // Arguments:
- // (1) the structure of the filter to be defined 2 EnterFilter
- // Returns: nothing
- //
- void EnterFilter(TheFilter &Filter)
- {
- // initialize the data structure that holds the filter, including getting the number of
- delete[] Filter.Values;
- // filter values from the user
- cout << "Please enter the number of filter values would you like to add? (this must be less than Data values)" << endl;
- cin >> Filter.Length;
-
- // allocate memory to the filter values
- // Obtain memory from free store for the array
- // obtain all of the data values
- Filter.Values = new double[Filter.Length];
- if (Filter.Values == 0)
- {
- cerr << "\n*** Unable to allocate memory *** \n";
- exit(1);
- }
- else
- {
- // obtain all of the filter values
- for (unsigned int i = 0; i < (Filter.Length); i++)
- {
- cout << "Enter data value " << i + 1 << ":" << endl;
- cin >> *(Filter.Values + i);
- }
- }
- cout << "Filter Assigned" << endl;
-
- Filter.Valid = true;
-
- }
-
- // Apply the filter to the input data and store in the filtered data structure 3 ApplyFilter
- // Arguments:
- // (1) the structure of the filter to be applied
- // (2) the structure containing the data to be filtered
- // (3) the structure to hold the filtered data
- // Returns: OK - if the filter is applied
- // FILTER_TOO_LONG - the filter is longer than the data
- //
- int ApplyFilter(TheFilter &Filter, TheData &DataIn, TheData &FilteredData)
- {
- // return an error if the filter is longer than the data
- if (Filter.Length > DataIn.Length) return FILTER_TOO_LONG;
-
- // initialize the data structure that holds the filtered data
- FilteredData.Length = (DataIn.Length - (Filter.Length - 1));
-
-
- // get memory for the filtered data
- FilteredData.Values = new double[Filter.Length];
- if (FilteredData.Values == 0)
- {
- cerr << "\n*** Unable to allocate memory *** \n";
- exit(1);
- }
- else
- {
- for (unsigned int j = 0; j < (FilteredData.Length); j++)
- {
- *(FilteredData.Values + j) = 0;
-
- for (unsigned int i = 0; i < (Filter.Length); i++)
- {
- *(FilteredData.Values + j) = (*(Filter.Values + i)) * (*(DataIn.Values + j + i)) + (*(FilteredData.Values + j));
- }
- }
- }
-
- Filter.Valid = true;
-
- return OK;
- }
-
-
- // Display input data, filter values and output data 4 DisplayData
- // Arguments:
- // (1) the structure of the filter to be applied
- // (2) the structure containing the data to be filtered
- // (3) the structure that holds the filtered data
- // Returns: nothing
- //
- void DisplayData(TheFilter &Filter, TheData &DataIn, TheData &FilteredData)
- {
- // display all of the input data values
- cout << "data values: ";
- for (unsigned int i = 0; i < (DataIn.Length); i++)
- {
- cout << *(DataIn.Values + i) << ", ";
- }
- cout << endl;
-
- // display all of the filter values
- cout << "filter values: ";
- for (unsigned int i = 0; i < (Filter.Length); i++)
- {
- cout << *(Filter.Values + i) << ", ";
- }
- cout << endl;
-
- // display all of the data output values
- cout << "filtered values: ";
- for (unsigned int i = 0; i < (FilteredData.Length); i++)
- {
- cout << *(FilteredData.Values + i) << ", ";
- }
- cout << endl;
- }
- [/tpcode]