1. [tpcode]
  2. // Purpose
  3. // A program to demonstrate the application of a simple digital filter
  4. //
  5. // Overview
  6. // A sequence of data items and digital filter values need to be entered by the
  7. // user. The application of the filter to the data involves a simple convolution
  8. // operation. The filtered data are stored separately.
  9. //
  10. // Example
  11. // before filtering:
  12. // data_in = [0 1 3 6 3 1 0]
  13. // filter = [-0.5 1 -0.5]
  14. // after filtering:
  15. // data_out = [-0.5 -0.5 3 -0.5 -0.5]
  16. // where
  17. // data_out[0]=data_in[0]*filter[0]+data_in[1]*filter[1]+data_in[2]*filter[2]
  18. // data_out[1]=data_in[1]*filter[0]+data_in[2]*filter[1]+data_in[3]*filter[2]
  19. // data_out[2]=data_in[2]*filter[0]+data_in[3]*filter[1]+data_in[4]*filter[2]
  20. // data_out[3]=data_in[3]*filter[0]+data_in[4]*filter[1]+data_in[5]*filter[2]
  21. // data_out[4]=data_in[4]*filter[0]+data_in[5]*filter[1]+data_in[6]*filter[2]
  22. //
  23. // The program checks the following
  24. // 1.The data and filter values must have been entered before the filter is
  25. // applied
  26. // 2.The filter is not applied if the number of filter values is greater than
  27. // the number of input data values
  28. // 3.The data and filter values must have been entered and the filter applied
  29. // before the filtered data can be displayed
  30. #include <iostream>
  31. using namespace std;
  32. // the data values and the filter
  33. struct TheFilter {
  34. double* Values; // the filter values POINTER
  35. unsigned long Length; // number of filter values
  36. bool Valid; // true if the filter values have been obtained
  37. };
  38. struct TheData {
  39. double* Values; // holds the data to be filtered POINTER
  40. unsigned long Length; // number of data values
  41. bool Valid; // true if the data values have been obtained
  42. };
  43. // function return values
  44. enum { OK, FILTER_TOO_LONG };
  45. // function prototypes
  46. void EnterData(TheData &OriginalData); //Function Prototypes
  47. void EnterFilter(TheFilter &Filter);
  48. int ApplyFilter(TheFilter &Filter, TheData &OriginalData, TheData &FilteredData);
  49. void DisplayData(TheFilter &Filter, TheData &OriginalData, TheData &FilteredData);
  50. // Control the principal operations of the program
  51. // Arguments: None
  52. // Returns: 0 on completion
  53. int main()
  54. {
  55. // define the filter and its initial values
  56. TheFilter Filter = { 0,0,false };
  57. // define the original data and its initial values
  58. TheData OriginalData = { 0,0,false };
  59. // define the filtered data and its initial values
  60. TheData FilteredData = { 0,0,false };
  61. char UserInput;
  62. // loop until the user wishes to exit
  63. while (1) {
  64. // show the menu of options
  65. cout << endl;
  66. cout << "Filter Menu" << endl;
  67. cout << "-----------" << endl;
  68. cout << "1. Enter data for filtering" << endl;
  69. cout << "2. Enter filter values" << endl;
  70. cout << "3. Apply filter" << endl;
  71. cout << "4. Display filtered data" << endl;
  72. cout << "5. Exit from the program" << endl << endl;
  73. // get the user's choice
  74. cout << "Enter your option: ";
  75. cin >> UserInput;
  76. cout << endl;
  77. // act on the user's input
  78. switch (UserInput) {
  79. case '1':
  80. EnterData(OriginalData);
  81. FilteredData.Valid = false;
  82. break;
  83. case '2':
  84. EnterFilter(Filter);
  85. FilteredData.Valid = false;
  86. break;
  87. case '3':
  88. if (Filter.Valid == true && OriginalData.Valid == true && FilteredData.Valid == false) {
  89. if (ApplyFilter(Filter, OriginalData, FilteredData) == FILTER_TOO_LONG) {
  90. cout << "The filter must not be longer than the data" << endl;
  91. }
  92. else {
  93. FilteredData.Valid = true;
  94. cout << "Filter applied" << endl;
  95. }
  96. }
  97. break;
  98. case '4':
  99. if (Filter.Valid == true && OriginalData.Valid == true && FilteredData.Valid == true) {
  100. DisplayData(Filter, OriginalData, FilteredData);
  101. }
  102. else {
  103. cout << "Data have not yet been filtered" << endl;
  104. }
  105. break;
  106. case '5':
  107. delete[] Filter.Values;
  108. delete[] OriginalData.Values;
  109. delete[] FilteredData.Values;
  110. return 0;
  111. break;
  112. default:
  113. cout << "Invalid entry" << endl << endl;
  114. break;
  115. }
  116. }
  117. }
  118. // Allow the user to enter the data to be filtered 1 EnterData
  119. // Arguments:
  120. // (1) the structure containing the input data
  121. // Returns: nothing
  122. //
  123. void EnterData(TheData &OriginalData)
  124. {
  125. // initialize the data structure that holds the data to be filtered, including getting
  126. delete[] OriginalData.Values;
  127. // the number of data values from the user
  128. cout << "Please enter the number of data values would you like to convolute?" << endl;
  129. cin >> OriginalData.Length;
  130. // allocate memory to the data
  131. // Obtain memory from free store for the array
  132. OriginalData.Values = new double[OriginalData.Length];
  133. if (OriginalData.Values == 0)
  134. {
  135. cerr << "\n*** Unable to allocate memory *** \n";
  136. exit(1);
  137. }
  138. else
  139. {
  140. // obtain all of the data values
  141. for (unsigned int i = 0; i < (OriginalData.Length); i++)
  142. {
  143. cout << "Enter data value " << i + 1 << ":" << endl;
  144. cin >> *(OriginalData.Values + i);
  145. }
  146. }
  147. cout << "Data Assigned" << endl;
  148. OriginalData.Valid = true;
  149. }
  150. // Allow the user to enter the filter values
  151. // Arguments:
  152. // (1) the structure of the filter to be defined 2 EnterFilter
  153. // Returns: nothing
  154. //
  155. void EnterFilter(TheFilter &Filter)
  156. {
  157. // initialize the data structure that holds the filter, including getting the number of
  158. delete[] Filter.Values;
  159. // filter values from the user
  160. cout << "Please enter the number of filter values would you like to add? (this must be less than Data values)" << endl;
  161. cin >> Filter.Length;
  162. // allocate memory to the filter values
  163. // Obtain memory from free store for the array
  164. // obtain all of the data values
  165. Filter.Values = new double[Filter.Length];
  166. if (Filter.Values == 0)
  167. {
  168. cerr << "\n*** Unable to allocate memory *** \n";
  169. exit(1);
  170. }
  171. else
  172. {
  173. // obtain all of the filter values
  174. for (unsigned int i = 0; i < (Filter.Length); i++)
  175. {
  176. cout << "Enter data value " << i + 1 << ":" << endl;
  177. cin >> *(Filter.Values + i);
  178. }
  179. }
  180. cout << "Filter Assigned" << endl;
  181. Filter.Valid = true;
  182. }
  183. // Apply the filter to the input data and store in the filtered data structure 3 ApplyFilter
  184. // Arguments:
  185. // (1) the structure of the filter to be applied
  186. // (2) the structure containing the data to be filtered
  187. // (3) the structure to hold the filtered data
  188. // Returns: OK - if the filter is applied
  189. // FILTER_TOO_LONG - the filter is longer than the data
  190. //
  191. int ApplyFilter(TheFilter &Filter, TheData &DataIn, TheData &FilteredData)
  192. {
  193. // return an error if the filter is longer than the data
  194. if (Filter.Length > DataIn.Length) return FILTER_TOO_LONG;
  195. // initialize the data structure that holds the filtered data
  196. FilteredData.Length = (DataIn.Length - (Filter.Length - 1));
  197. // get memory for the filtered data
  198. FilteredData.Values = new double[Filter.Length];
  199. if (FilteredData.Values == 0)
  200. {
  201. cerr << "\n*** Unable to allocate memory *** \n";
  202. exit(1);
  203. }
  204. else
  205. {
  206. for (unsigned int j = 0; j < (FilteredData.Length); j++)
  207. {
  208. *(FilteredData.Values + j) = 0;
  209. for (unsigned int i = 0; i < (Filter.Length); i++)
  210. {
  211. *(FilteredData.Values + j) = (*(Filter.Values + i)) * (*(DataIn.Values + j + i)) + (*(FilteredData.Values + j));
  212. }
  213. }
  214. }
  215. Filter.Valid = true;
  216. return OK;
  217. }
  218. // Display input data, filter values and output data 4 DisplayData
  219. // Arguments:
  220. // (1) the structure of the filter to be applied
  221. // (2) the structure containing the data to be filtered
  222. // (3) the structure that holds the filtered data
  223. // Returns: nothing
  224. //
  225. void DisplayData(TheFilter &Filter, TheData &DataIn, TheData &FilteredData)
  226. {
  227. // display all of the input data values
  228. cout << "data values: ";
  229. for (unsigned int i = 0; i < (DataIn.Length); i++)
  230. {
  231. cout << *(DataIn.Values + i) << ", ";
  232. }
  233. cout << endl;
  234. // display all of the filter values
  235. cout << "filter values: ";
  236. for (unsigned int i = 0; i < (Filter.Length); i++)
  237. {
  238. cout << *(Filter.Values + i) << ", ";
  239. }
  240. cout << endl;
  241. // display all of the data output values
  242. cout << "filtered values: ";
  243. for (unsigned int i = 0; i < (FilteredData.Length); i++)
  244. {
  245. cout << *(FilteredData.Values + i) << ", ";
  246. }
  247. cout << endl;
  248. }
  249. [/tpcode]