I have a c++ function for an RRC filter. The code. compiles and runs smoothly, but it gives a NaN output for a specified complex function.
The code in question is:
std::complex<float> rrc_output(const std::vector<std::complex<float>>& ht,
const std::deque<std::complex<float>>& rrc_sample_buffer){
std::complex<float> yt = 0.;
for (int n = 0; n < ht.size(); n++)
yt += ht[n]*rrc_sample_buffer[n];
return yt;
}
For more. clarity, the rrc _sample_buffer takes in 2-tuple inputs, (x,y) from a text file, and the ht is defined by the following formulae with conditions attached:
for (int i = 1; i< ht.size()+1; i++){
if (t == 0){
ht[i] = Rs*(1+(beta*((4/pi)-1)));
}
else if ( t == (Ts/(4*beta)) || t == -(Ts/(4*beta))){
ht[i] = (beta/Ts*sqrt(2))*((1+(2/pi))*sin(pi/(4*beta))+(1-(2/pi))*cos(pi/(4*beta)));
}
else{
ht[i] = (Rs*(sin(pi*t*Rs*(1-beta))+(4*beta*t*Rs*cos(pi*t*Rs*(1-beta)))))/(pi*t*Rs*(1-pow((4*beta*t*Rs),2)));
}
where the length of ht and rrc_sample_buffer are:
vector<complex<float>> ht(sps, 0);
std::deque<complex<float>> rrc_sample_buffer(ht.size(), 0.);
Any ideas on how I can get this fixed?
Thank you.
Related
Just started using cLion as an ide for c++. Am attempting to run this block of code where it reads a csv file and stores the values in a 189 x 141 2d vector. It then iterates through 5 for loops. Everything was running smoothly until I included the 5 nested for loops; at this point I was seeing the "Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)" message upon executing. I have seen an answer to a similar question claiming that it is the result of a lack of memory on my computer. Would this be the case?
When the first 3 for loops have ib0, ib1, ib2 iterate from 0 to 100, it would of course mean that there are over 26 billion iterations in total. However, when I reduce this range to 0 to 1, I still receive the message.
For reproducibility, I just have the ROB vector be 189 x 141 random values.
EDIT: If anyone runs this code, let me know how long it takes?
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int main() {
double innerarrayval;
vector<vector<double>> ROB;
vector<double> innerarray;
for(int x=0;x<189;x++) {
innerarray.clear();
for (int y = 0; y < 141; y++) {
innerarrayval = rand() % 1000;
innerarray.push_back(innerarrayval);
}
ROB.push_back(innerarray);
}
double b0,b1,b2;
int nnb;
double chisquared, amean, content, sumpart, sumpartsquared,chisquaredNDOF,chimin;
double b0mem, b1mem, b2mem;
chimin = 1000.0;
for(int ib0 = 0; ib0 < 101; ib0++)
{
b0 = 15.0 + 0.1 * (ib0 - 1);
for(int ib1 = 0; ib1 < 101; ib1++)
{
b1 = -0.002 * (ib1 - 1);
for(int ib2 = 0; ib2 < 101; ib2++)
{
b2 = 0.002 * (ib2 - 1);
nnb = 0;
chisquared = 0;
amean = 0;
for(int i = 0; i <= 189; i++)
{
for(int j = 0; j <= 141; j++)
{
if((i >= 50 and i <= 116) and (j >= 42 and j <= 112))
{
continue;
}
else
{
content = ROB[i][j];
if(content == 0)
{
content = 1;
}
amean = amean + content;
sumpart = (content - b0 - (b1 * i) - (b2 * j))/sqrt(content);
sumpartsquared = pow(sumpart, 2);
chisquared = chisquared + sumpartsquared;
nnb = nnb + 1;
}
}
}
chisquaredNDOF = chisquared/double(nnb);
amean = amean/double(nnb);
if(chisquaredNDOF < chimin)
{
chimin = chisquaredNDOF;
b0mem = b0;
b1mem = b1;
b2mem = b2;
}
}
}
}
cout<<"chi squared: "<<chimin<<"\n";
cout<<"b0: "<<b0mem<<"\n";
cout<<"b1: "<<b1mem<<"\n";
cout<<"b2: "<<b2mem<<"\n";
cout<<"mean: "<<amean<<"\n";
return 0;
}
for(int x=0;x<189;x++) {
innerarray.clear();
for (int y = 0; y < 141; y++) {
innerarrayval = rand() % 1000;
innerarray.push_back(innerarrayval);
}
ROB.push_back(innerarray);
}
This part of the initialization loops carefully, and gingerly, initialized the two-dimensional ROB vector. As noted by each for loop's limit, the valid indexes for the first dimension is 0-188, and the 2nd dimension is 0-140.
This is correct. In C++ array/vector indexes start with 0, so for your expected result of a "189 x 141 2d vector", the first index's values range 0-188, and the 2nd one's range is 0-140.
If you proceed further in your code, to the part that reads the two-dimensional matrix:
for(int i = 0; i <= 189; i++)
{
for(int j = 0; j <= 141; j++)
{
And because this uses <=, this will attempt to access values in ROB whose first dimension's index range is 0-189 and the 2nd dimension's index range is 0-141.
The out of bounds access results in undefined behavior, and your likely crash.
You should use this obvious bug as an excellent opportunity for you to learn how to use your debugger. If you used your debugger to run this program, the debugger would've stopped at the point of the crash. If you then used your debugger to inspect the values of all variables, I would expect that the out-of-range values for i or j would be very visible, making the bug clear.
I'm writing a simple program in which I take a .txt file read it and encrypt or decrypt it with the Playfair algorithm using a 16x16 ASCII cipher.
When I decypher a file I get it mostly correct the only issue is that the char 'o' is replaced with '_' and random sections of the text are not deciphered right.
Example:
"as she swam l z}"d~o*dd/y``6� {;/~v_(tb_)uesp4�prxnc(z�icehr,P`(yc'eezm"-ickin_)"
This is the section of the code that I use to decipher it. At this point I already generated the matrix and read the input file. In the encryption code if a and b are equal b is set to NULL, the last if statement checks that. The variable besedilo is the whole text of the file and M is the 16x16 matrix.
for(int t = 0; t < besedilo.size()-2;t+=2){
char a = besedilo[t];
char b = besedilo[t+1];
int it, jt, k = 0,f = 0, i=0,j=0;
for(it = 0; it < 16; it++){
for(jt = 0; jt < 16; jt++){
if(a == M[it][jt]){
i = it;
j = jt;
}
if(b == M[it][jt]){
k = it;
f = jt;
}
}
}
if((i != k)&&(j != f)){
a = M[i][f];
b = M[k][j];
}else if(i == k){
a = M[i][(j-1)%16];
b = M[k][(f-1)%16];
}else if(j == f){
a = M[(i-1)%16][j];
b = M[(k-1)%16][f];
}
if(b == NULL){
b = a;
}
Your issue is that % does not wrap with negative numbers. Instead you are indexing negatively when any of your positions are in the 0th column or index as then you are doing (0 - 1) % 16 which is -1. See this response here: Modulo operator with negative values for the issue.
You can easily solve this with a small helper function that handles the wrapping for you, see How to make the mod of a negative number to be positive? for a possible solution.
I wrote the following dp code for finding the prime factors of a number.
#include <bits/stdc++.h>
#define max 1000001
using namespace std;
vector <int> prime;
vector<bool> isprime(max,true);
vector<bool> visited(max,false);
vector<int> data(max,-1);
void dp(int n,int last)
{
if(n >= max || visited[n])
return;
visited[n] = true;
for(int i = last;i<prime.size();i++)
{
if(n*prime[i] >= max || data[n*prime[i]] != -1)
return;
data[n*prime[i]] = prime[i];
dp(n*prime[i],i);
}
}
int main()
{
isprime[1] = false;
data[1] = 1;
for(int i = 4;i<max;i += 2)
isprime[i] = false;
for(int i = 3; i*i< max;i += 2)
{
for(int j = i*i; j < max;j += i)
isprime[j] = false;
}
prime.push_back(2);
data[2] = 2;
for(int i =3;i<max;i += 2)
if(isprime[i])
{
prime.push_back(i);
data[i] = i;
}
for(int i = 0;i<prime.size();i++)
{
dp(prime[i],i);
}
cout<<"...1\n";
for(int i = 2;i<=8000;i++)
{
cout<<i<<" :- ";
int temp = i;
while(temp!= 1)
{
cout<<data[temp]<<" ";
temp = temp/data[temp];
}
cout<<endl;
}
return 0;
}
Here, last is the last index of prime number n.
But I am getting segmentation fault for this, when I change max to 10001, it runs perfectly. I'm not getting why is this happening since the data-structures used are 1-d vectors which can hold values up to 10^6 easily.
I checked your program out using GDB. The segfault is taking place at this line:
if(n*prime[i] >= max || data[n*prime[i]] != -1)
In your first ever call to DP in your for loop, where you call dp(2,0), the recursive calls eventually generate this call: dp(92692,2585).
92692 * 2585 = 239608820
This number is larger than a 32 bit integer can hold, so the r-value generated by the integer multiplication of those two numbers overflows and becomes negative. nprime[i] becomes negative, so your first condition of the above loop fails, and the second is checked. data[n * prime[i]] is accessed, and since n*prime[i] is negative, your program accesses invalid memory and segfaults. To fix this, simply change n to a long long in your parameter list and you should be fine.
void dp(long long n, int last)
I have a bunch of maths manipulations that have thresholds, yet no matter what I change, the if statements always return true. No compile errors, can't get the debugger to work. This is a function, the X Y and Z arrays are all correct (I printed them to check earlier), the maths is right at least for the blade distance check, yet that always returns true. I ran the same code (rewritten obviously) through matlab and that returns true or false depending on my data, so clearly its something with the way I've written this that's wrong. Also is there any way to slimline this?
bool Device::_SafeD(char _Type, float _Data[20][3]) {
bool S;
double x[20], y[20], z[20];
for (int i=0; i<20; i++) {
x[i] = _Data[i][0];
y[i] = _Data[i][1];
z[i] = _Data[i][2];
}
// Check angles for needle
if (_Type == 'n') {
for (int i=0; i<20; i++) {
float dot, moda, modb, c, angle;
dot = ((x[i]*x[i+1]) + (y[i]*y[i+1]) + (z[i]*z[i+1]));
moda = sqrt(pow(x[i],2)+pow(y[i],2)+pow(z[i],2));
modb = sqrt(pow(x[i+1],2)+(y[i+1],2)+(z[i+1],2));
c = dot/(moda*modb);
angle = acos(c);
if (angle > 45){
S = 0;
} else {
S = 1;
}
}
}
// Check distance for blade
if (_Type == 'b'){
for (int i=0; i<19; i++) {
float distance = (x[i+1]-x[i]) + (y[i+1]-y[i]) + (z[i+1]-z[i]);
cout << "distance " << distance << endl;
if (distance > 5.0) {
S = 0;
} else {
S = 1;
}
}
}
if (S == 0) {
return 0;
}
if(S == 1) {
return 1;
}
}
Cheers
The most likely error is that you are comparing angle to an angle in degree while the return value of acos is in radians.
if (angle > 45){
Convert the angle to degrees before comparing to 45 and you should be OK.
if (radians_to_degrees(angle) > 45){
where
double radians_to_degrees(double in)
{
return (in*180/M_PI);
}
Another option is to compute the equivalent of 45 degrees in radians and compare it with angle.
double const radian_45 = M_PI*45.0/180;
and use
if (angle > radian_45){
The other error is spelled out clearly in a comment by #Bob__:
OP uses two loops to check the angle and the distance, inside those loops a flag (S) is set to 0 or 1, but it's done for every index in the array, so it's overwritten. The return value of the entire function (in the provided code) depends only by the last two elements in the array.
How do I speed up this recursive function? When it reaches a 10x10 matrix, it takes up a minute or so just to solve a problem. I included the event function as well so you can see when the calculation would take place.
void determinantsFrame::OnCalculateClick(wxCommandEvent &event)
{
double elem[MAX][MAX]; double det; string test; bool doIt = true;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
test = (numbers[i][j]->GetValue()).mb_str();
if (test == "")
{
doIt = false;
break;
}
for (int k = 0; k < test.length(); k++)
if (isalpha(test[k]) || test[k] == ' ')
{
doIt = false;
break;
}
else if (ispunct(test[k]))
{
if (test[k] == '.' && test.length() == 1)
doIt = false;
else if (test[k] == '.' && test.length() != 1)
doIt = true;
else if (test[k] != '.')
doIt = false;
}
if (doIt == false)
break;
}
if (doIt == false)
break;
}
if (doIt)
{
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
elem[i][j] = static_cast<double>(wxAtof(numbers[i][j]->GetValue()));
det = determinant(elem, n);
wxMessageBox(wxString::Format(wxT("The determinant is: %.4lf"),det));
}
else
wxMessageBox(wxT("You may have entered an invalid character. Please try again"));
}
double determinantsFrame::determinant(double matrix[MAX][MAX], int order) // Here's the recursive algorithm
{
double det = 0; double temp[MAX][MAX]; int row, col;
if (order == 1)
return matrix[0][0];
else if (order == 2)
return ((matrix[0][0] * matrix[1][1]) - (matrix[0][1] * matrix[1][0]));
else
{
for (int r = 0; r < order; r++)
{
col = 0; row = 0;
for (int i = 1; i < order; i++)
{
for (int j = 0; j < order; j++)
{
if (j == r)
continue;
temp[row][col] = matrix[i][j];
col++;
if (col == order - 1)
col = 0;
}
row++;
}
det = det + (matrix[0][r] * pow(-1, r) * determinant(temp, order - 1));
}
return det;
}
}
You can do a bit better with keeping the same algorithm but it is at least O(n!) (probably worse) so higher order matrices will be slow no matter how much you optimize it. Note I did the benchmark times in MSVC 2010 and are there only for rough comparison purposes. Each change is cumulative as you go down the list and is compared to the original algorithm.
Skip Col Check -- As Surt suggested, removing this gets us a speed increase of 1%.
Add 3x3 Case -- Adding another explicit check for a 3x3 matrix gets us the most, 55%
Change pow() -- Changing the pow() call to (r % 2 ? -1.0 : 1.0) gets us a little bit more, 57%
Change to switch -- Changing the order check to a switch gets us a little bit more, 58%
Add 4x4 Case -- Adding another explicit check for a 4x4 matrix gets more, 85%
Things that don't work include:
memcpy -- As Surt suggested this actually looses a good deal of speed, -100%
Threads -- Creating order threads doesn't work well at all, -160%
I was hoping that using threads could get us a significant performance increase but even with all the optimization it is slower than the original. I think the copying of all the memory is making it not very parallel.
Added the 3x3 and 4x4 cases has the most effect and are the primary reason for the over x6 increase in speed. In theory you could add more explicit cases (probably by creating a program to output the required code) to reduce the speed even further. Of course, at some point this kind of defeats the purpose of using a recursive algorithm to begin with.
To get more performance you would probably have to consider a different algorithm. In theory you can change the recursive function into an iterative one by managing your own stack but it is considerable work and you aren't guaranteed a performance increase anyways.
It could be a branch mispredict problem (see also). The test
if (col == order - 1)
col = 0;
Is not needed as far as I can see.
The test fails 1/order times per loop and dominates for small order, which is why larger N aren't so affected. The timing is still large O(N!^3) (afaik) so don't expect miracles.
col = 0; row = 0;
for (int i = 1; i < order; i++) {
for (int j = 0; j < order; j++) {
if (j == r)
continue;
temp[row][col] = matrix[i][j];
col++;
//if (col == order - 1)
// col = 0;
}
col = 0; // no need to test
row++;
}
The algorithm will get a further slowdown when it hit L2 cache, at latest at N=64.
Also the matrix copy might be ineffective, this could be far more effective for large order at the cost of low effectiveness at low order.
for (int r = 0; r < order; r++) {
row = 0;
for (int i = 1; i < order; i++) {
memcpy(temp[row], matrix[i], r*sizeof(double)); // if r==0 will this work?
memcpy(&temp[row][r], &matrix[i][r+1], (order-r-1)*sizeof(double));
// amount of copied elements r+(order-r-1)=order-1.
row++;
}
Make a test with the original code to get the determinant that I got the indexes right!