Infinite Impluse Response (IIR) Function - c++

I am trying to design a signal class which includes an IIR filter function. The following is my code:
void signal::IIRFilter(vector<double> coefA, vector<double> coefB){
double ** temp;
temp = new double*[_nchannels];
for(int i = 0; i < _nchannels; i++){
temp[i] = new double[_ninstances];
}
for(int i = 0; i < _nchannels; i++){
for(int j = 0; j < _ninstances; j++){
temp[i][j] = 0;
}
}
for(int i = 0; i < _nchannels; i++){
for (int j = 0; j < _ninstances; j++){
int sum1 = 0;
int sum2 = 0;
for(int k = 0; k < coefA.size(); k++){
if ((j-k) > 0 ){
sum1 += coefA.at(k)*temp[i][j-k-1];
}
}
for (int m = 0; m < coefB.size(); m++){
if(j >= m){
sum2 += coefB.at(m)*_data[i][j-m];
}
}
temp[i][j] = sum2-sum1;
}
}
for(int i = 0; i < _nchannels; i++){
for(int j = 0; j < _ninstances; j++){
_data[i][j] = temp[i][j];
}
}
}
_data contains my original signal, _ninstances is my number of samples, and _nchannels is the number of channels. The function compiles and works but the result I am getting is different from the result given by MATLAB. I even use the same coefficients given by MATLAB. Is there anything that I'm doing wrong in my function?

One issue that I can see is that you are declaring sum1 and sum2 as integers when they should be double. To avoid this kind of error in the future, you should try configuring your compiler to warn of implicit conversions. In g++, this is accomplished using the -Wconversion flag.

Related

C++ Gauss–Seidel method

this is a piece of code for a simple iteration method for solving systems of linear algebraic equations:
double* iter(double** a, double* y, int n, int& iter)
{
double* res = new double[n];
int i, j;
for (i = 0; i < n; i++)
{
res[i] = y[i] / a[i][i];
}
double eps = 0.0001;
double* Xn = new double[n];
do {
iter++;
for (i = 0; i < n; i++) {
Xn[i] = y[i] / a[i][i];
for (j = 0; j < n; j++) {
if (i == j)
continue;
else {
Xn[i] -= a[i][j] / a[i][i] * res[j];
}
}
}
bool flag = true;
for (i = 0; i < n - 1; i++) {
if (fabs(Xn[i] - res[i]) > eps) {
flag = false;
break;
}
}
for (i = 0; i < n; i++) {
res[i] = Xn[i];
}
if (flag)
break;
} while (1);
return res;
}
and formula for it:
but I would like to implement the seidel method.and slightly changed the code according to the formula below
for (i = 0; i < n; i++) {
Xn[i] = y[i] / a[i][i];
for (j = 0; j < i-1; j++) {
Xn[i] -= a[i][j] / a[i][i] * Xn[j];
}
for (j = i+1; j < n; j++){
Xn[i] -= a[i][j] / a[i][i] * res[j];
}
}
but I'm not getting exactly what I expected:
I would be grateful if you could tell me where I made a mistake. thank you in advance for your answers.
Your mistake lies in the new implementation.
The first sum of the Seidel method sums up to the element before the diagonal, while your for loop goes up to two elements before the diagonal.
Instead of
for(j = 0; j < i-1; j++)
you should have
for(j = 0; j < i; j++)
Note that Gauss Seidel method is applicable if the elements on the diagonal are non-zero.

how to improve performance of 2d array in C++

I have a low-level function that will be called millions of times, so it should be very efficient. When I use "gprof" in Linux, I found that a part of the code takes 60% of the total computation of the function (the rest part is to solve the roots of a cubic equation). Here Point is a data structure has x and v, which will be converted to a matrix for later use. The idea is to subtract each row by the first row. The code shows like below
double x[4][3] = {0}, v[4][3] = {0};
for (int i = 0; i < 4; ++i){
for (int j = 0; j < 3; ++j){
v[i][j] = Point[i]->v[j];
x[i][j] = Point[i]->x[j];
}
}
for (int i = 1; i < 4; ++i){
for (int j = 0; j < 3; ++j){
v[i][j] = v[0][j] - v[i][j];
x[i][j] = x[0][j] - x[i][j];
}
}
Can anyone show me the problem of this code? Why it performs so badly?
You can do it all in one pass:
double x[4][3] = {
{ Point[0]->x[0], Point[0]->x[1], Point[0]->x[2] }
};
double v[4][3] = {
{ Point[0]->v[0], Point[0]->v[1], Point[0]->v[2] }
};
for (int i = 1; i < 4; ++i){
for (int j = 0; j < 3; ++j){
x[i][j] = x[0][j] - Point[i]->x[j];
v[i][j] = v[0][j] - Point[i]->v[j];
}
}
You could even take that to the next level and put the entire thing into the initializers for x and v.
Or, if x and v in Point are each contiguous arrays:
double x[4][3], v[4][3]; // no init
// fill entire arrays
for (int i = 0; i < 4; ++i){
memcpy(x[0], Point[0]->x, sizeof(x[0]));
memcpy(v[0], Point[0]->v, sizeof(v[0]));
}
for (int i = 1; i < 4; ++i){
for (int j = 0; j < 3; ++j){
x[i][j] -= Point[i]->x[j];
v[i][j] -= Point[i]->v[j];
}
}

C++: Sorting strings using LSD radix sort crashing

I have written some code that is meant to sort an array of strings using the radix sort, starting with the least significant digit. This function assumes all of the strings are the same length and each character is lowercase.
I am encountering crashes whenever I get to the loop in which I assign values to the temporary array. You can see my function here:
#ifndef RADIX_H
#define RADIX_H
#include <string>
#include <iostream>
using namespace std;
void lsd_string_radix(string array[], int array_size, int max_chars)
{
string *temp = new string[array_size];
for(int i = max_chars - 1; i >= 0; i--)
{
int count[26] = {0};
for(int j = 0; j < array_size; j++)
{
count[static_cast<int>(array[j][i]) - 97]++;
}
for(int j = 1; j <= 26; j++)
{
count[j] += count[j - 1];
}
for(int j = 0; j < array_size; j++)
{
temp[count[static_cast<int>(array[j][i])]++] = array[j]; // crashes here
}
for(int j = 0; j < array_size; j++)
{
array[j] = temp[j];
}
}
}
#endif
I'm guessing I have a failing in logic but I can't figure it out for the life of me.
After the second loop, count[0] should be zero, and the third loop is missing a -97. This example fixes the problem using count of size 27 instead of 26. The first loop in this example uses -96, so count[0] = 0, count[1] = # instances of 'a's, count[2] = # instances of 'b's, ... . count[26] = # instances of 'z's but it's only used in the first loop. It's not needed, but it's simpler to put a count of 'z's there rather than adding an if statement to avoid storing a count at count[26].
#include<iomanip>
#include<iostream>
#include <string>
using namespace std;
void lsd_string_radix(string array[], int array_size, int max_chars)
{
string *temp = new string[array_size];
for(int i = max_chars - 1; i >= 0; i--)
{
int count[27] = {0};
for(int j = 0; j < array_size; j++)
count[static_cast<int>(array[j][i]) - 96]++;
for(int j = 2; j < 26; j++)
count[j] += count[j - 1];
for(int j = 0; j < array_size; j++)
temp[count[static_cast<int>(array[j][i]) - 97]++] = array[j];
for(int j = 0; j < array_size; j++)
array[j] = temp[j];
}
}
int main()
{
string a[6] = {"mnop", "ijkl", "efgh", "uvwx", "qrst", "abcd"};
lsd_string_radix(a, 6, 4);
for(size_t i = 0; i < 6; i++)
cout << a[i] << endl;
return 0;
}
If the size of count[] is to be 26, the first loop needs to be modified:
for(int j = 0; j < array_size; j++){
if(array[j][i] == 'z')continue;
count[static_cast<int>(array[j][i]) - 96]++;
}
or the first two loops are modified:
for(int j = 0; j < array_size; j++)
count[static_cast<int>(array[j][i]) - 97]++;
int m = 0;
int n;
for(int j = 0; j < 26; j++){
n = count[j];
count[j] = m;
m += n;
}

C++ - my for loop is not starting

I wrote this code for java first. It should print the 2D array as a spiral. I wanted to try it in c++.. in java; there was a draw method. But c++ is not accepting array as a return type (can done by pointers) so I deleted the draw method and copied inside the main method. I commented the draw method where starts and ends. But now; the for loop which is after the draw method (i commented it too) is not starting. What's the problem; I cannot see it... Thanx for help.
int T ;
scanf("%d", &T);
int num[T];
for(int i = 0; i < T; i++){
scanf("%d", &num[i]);
}
for(int m = 0; m < T; m++){
int n = num[m];
int a[n][n];
//draw -start
int all = n*n;
int x = 0, y=0;
for(int counter=1; counter<=all; counter++){
for(int i = 0; i < n; i++){
a[x][y] = counter++;
y++;}
x++; y--;
for(int i = 0; i < n-1; i++){
a[x][y] = counter++;
x++;}
x--; y--;
for(int i = 0; i < n-1; i++){
a[x][y] = counter++;}
x--; y++;
for(int i = 0; i < n-2; i++){
a[x][y] = counter++;}
y++; x++; n = n-2;}
//draw - end
//this for is not starting
for(int i = 0; i<n; i++){
printf("a");
for(int j = 0; i<n; j++){
printf("a");
printf("%d ", a[i][j]);
}
printf("\n");
}
You decrement n in the biggest cycle.
n = n-2;
This is why n < 0 when you reach the for you speak of and it is not looping.
I am almost certain you did not meant to modify n in this loop.
I neatened up your code and provided my answer in the comments.
int T ;
scanf("%d", &T);
int num[T];
for(int i = 0; i < T; i++){
scanf("%d", &num[i]);
}
for(int m = 0; m < T; m++){
int n = num[m];
int a[n][n];
//draw -start
int all = n*n;
int x = 0, y=0;
for(counter=1; counter<=all; counter++){
for(int i = 0; i < n; i++) {
a[x][y] = counter++;
y++;
}
x++;
y--;
for(int i = 0; i < n-1; i++) {
a[x][y] = counter++;
x++;
}
x--;
y--;
for(int i = 0; i < n-1; i++) {
a[x][y] = counter++;
}
x--;
y++;
for(int i = 0; i < n-2; i++) {
a[x][y] = counter++;
}
y++;
x++;
n = n-2; //n = n - 2; all = n * n times?
}
for(int i = 0; i<n; i++){
printf("a");
for(int j = 0; i<n; j++){
printf("a");
printf("%d ", a[i][j]);
}
printf("\n");
}
}
in particular look at this line
n = n-2; //n = n - 2; all = n * n times?

c++ 3d arrays

I'm trying to run a 3d array but the code just crashes in windows when i run it, here's my code;
#include <iostream>
using namespace std;
int main(){
int myArray[10][10][10];
for (int i = 0; i <= 9; ++i){
for (int t = 0; t <=9; ++t){
for (int x = 0; x <= 9; ++t){
myArray[i][t][x] = i+t+x;
}
}
}
for (int i = 0; i <= 9; ++i){
for (int t = 0; t <=9; ++t){
for (int x = 0; x <= 9; ++t){
cout << myArray[i][t][x] << endl;
}
}
}
system("pause");
}
can someone throw me a quick fix / explanation
You twice have the line
for (int x = 0; x <= 9; ++t){
when you mean
for (int x = 0; x <= 9; ++x){
Classic copy-and-paste error.
BTW, if you run this in a debugger and look at the values of the variables, it's pretty easy to see what's going on.
David's answer is correct.
Incidentally, convention is to use i,j,and k for nested iterator indices, and also to use < array_length rather than <= array_length -1 as the terminator.
If you do that, then you can make the array size a constant and get rid of some magic numbers.
Also, an assertion at the point where you use the array indices might have pointed you to the error.
The result may look like:
const std::size_t ARRAY_SIZE = 10;
int myArray[ARRAY_SIZE][ARRAY_SIZE][ARRAY_SIZE];
for (std::size_t i = 0; i < ARRAY_SIZE; ++i)
{
for (std::size_t j = 0; j < ARRAY_SIZE; ++j)
{
for (std::size_t k = 0; k < ARRAY_SIZE; ++k)
{
std::assert (i < ARRAY_SIZE && j < ARRAY_SIZE && k < ARRAY_SIZE);
// Do stuff
}
}
}