Problem adapting a C code to Qt



  • Hi everyone,
    I´m a beginner on programming and Qt, but as liked the framework I´m trying to improve my skills and write my C++ codes on it. I got a task of writting a Ricker wavelet code and then plot it.
    I divided it in two tasks, first make the ricker code works, and when it is running, then implement a way to plot it, I will use qcustomplot for it.
    I got a code from C and I´m trying to adapt it to Qt. Although it doesn´t give any errors during compilation, when executing it crashes, with the following message:

    Invalid parameter passed to C runtime function.
    C:/Users/Flavio/Documents/qtTest/build-ricker2-Desktop_Qt_5_11_0_MinGW_32bit-Debug/debug/ricker2.exe exited with code 255

    The code I´m supposed to translate is:

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    float *rickerwavelet(float fpeak, float dt, int *nwricker);
    int main(int argc, char **argv)
    {
    int i;
    float dt;
    float fpeak;
    
    float *wricker=NULL;
    int nwricker;
    
    fpeak = atof(argv[1]);
    dt = atof(argv[2]);
    
    wricker = rickerwavelet(fpeak, dt, &nwricker);
    
    /* show value of ricker wavelets */
    for (i=0; i<nwricker; i++)
    printf("%i. %3.5f \n", i, wricker[i]);
    
    free(wricker);
    return(1);
    }
    
    /* ricker wavelet function, return an array ricker wavelets */
    float *rickerwavelet(float fpeak, float dt, int *nwricker)
    {
    int i, k;
    int nw;
    int nc;
    float pi;
    float nw1, alpha, beta;
    float *wricker=NULL;
    
    pi = 3.141592653589793;
    nw1 = 2.2/fpeak/dt;
    nw = 2*floor(nw1/2)+1;
    nc = floor(nw/2);
    
    wricker = (float*) calloc (nw, sizeof(float));
    for (i=0; i<nw; i++)
    {
    k = i+1;
    alpha = (nc-k+1)*fpeak*dt*pi;
    beta = pow(alpha, 2.0);
    wricker[i] = (1 - (beta*2)) * exp(-beta);
    }
    
    (*nwricker) = nw;
    return(wricker);
    }
    
    

    The code i wrote on Qt is:

    #include <QCoreApplication>
    #include <qmath.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <QDebug>
    
    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);
    int i,k,nw,nc;
    double *wricker=NULL;
    int nwricker = 60;
    int wavelet_freq = 30;
    int polarity=1;
    int sampling_rate=0.004;
    float nw1, alpha, beta;
    const double pi = 3.141592653589793238460;
    
    nw1 = 2.2/wavelet_freq/sampling_rate;
    nw = 2*floor(nw1/2)+1;
    nc = floor(nw/2);
    
    
    wricker = (double*)calloc (nw, sizeof(double));
    for (i=0; i<nw; i++)
    {
    k = i+1;
    alpha = (nc-k+1)*wavelet_freq*sampling_rate*pi;
    beta = pow(alpha, 2.0);
    wricker[i] = polarity*((1 - (beta*2)) * exp(-beta));
    };
    /* show value of ricker wavelets */
    for (i=0; i<nwricker; i++)
    {
    qDebug()<<i<<wricker[i];
    };
    
    free(wricker);
    
    return a.exec();
    }
    
    
    

    Analytic expression

    The amplitude A of the Ricker wavelet with peak frequency f at time t is computed like so:

    A = (1-2 pi^2 f^2* t^2) e^{-pi^2* f^2* t^2}

    A py code for it would be:

    import numpy as np
    import matplotlib.pyplot as plt
    
    def ricker(f, length=0.128, dt=0.001):
    t = np.arange(-length/2, (length-dt)/2, dt)
    y = (1.0 - 2.0*(np.pi**2)*(f**2)*(t**2)) * np.exp(-(np.pi**2)*(f**2)*(t**2))
    return t, y
    
    f = 25 # A low wavelength of 25 Hz
    t, w = ricker(f)
    

    What seems quite simple.

    Does anyone have any idea what is wrong in my code???

    Thanks in advance.


  • Qt Champions 2018

    Hi @Flavio-Mesquita, welcome to the forums.

    Although it doesn´t give any errors during compilation, when executing it crashes

    The best hint I can give you is: use a debugger to find out

    1. where your program crashes and
    2. why your program crashes.

    If you find where, but don't know why, ask again here. But if you let others search for the errors, you have zero learning effect and this doesn't help you in the long run.

    Regards



  • @aha_1980 Ok, I used the Debug, although I´m not sure if i used it right, I followed the instructions on the help manual.
    According to it, the problem is when passing the vectors to qDebug, it give a message:

    THE INFERIOR STOPPED BECAUSE IT RECEIVED A SIGNAL FROM THE OPERATING SYSTEM .
    SIGNAL NAME: SIGSEGV
    SIGNAL MEANING: SEGMENTATION FAULT

    I´ll search for more information on this meaning. I used qDebug only with the intention of showing the data on a terminal, actually I want to plot the arrays: wricker and i.


  • Moderators

    @Flavio-Mesquita So now that you have it crashing (segfault), you run a backtrace and it will show you the call stack. This will tell you where you crashed in your application.

    If you want further help post the backtrace here.


  • Qt Champions 2018

    @Flavio-Mesquita said in Problem adapting a C code to Qt:

    qDebug()<<i<<wricker[i];

    Is it in this place? If so then most probably it is not related to qDebug, but to wricker[i] - I guess you have less entries in wricker than nwricker.


  • Qt Champions 2018

    #include <vector>
    #include <cmath>
    #include <iostream>
    #include <QCommandLineParser>
    #include <QCoreApplication>
    std::vector<double> rickerwavelet(double fpeak, double dt)
    {
        const double nw1 = 2.2/fpeak/dt;
        const int nwricker = (2*std::floor(nw1/2.0))+1;
        const int nc = std::floor(nwricker/2.0);
        const double pi = std::atan(1.0)*4.0;
        std::vector<double> wricker;
        wricker.reserve(nwricker);
        for (int i=0; i<nwricker; ++i){
            const double alpha = (nc-i+2)*fpeak*dt*pi;
            const double beta = std::pow(alpha, 2.0);
            wricker.push_back((1 - (beta*2)) * std::exp(-beta));
        }
        return wricker;
    }
    int main(int argc, char **argv)
    {
        QCoreApplication a(argc, argv);
        QCommandLineParser parser;
        parser.setApplicationDescription("Ricker wavelet");
        parser.addHelpOption();
        parser.addPositionalArgument("fpeak","Peak Frequency");
        parser.addPositionalArgument("dt","Time");
        parser.process(a);
        const QStringList args = parser.positionalArguments();
        if(args.size()!=2){
            std::cout << "Invalid Input!" << std::endl;
            parser.showHelp(1);
        }
        bool conversionOk;
        const double fpeak = args.first().toDouble(&conversionOk);
        if(!conversionOk){
            std::cout << "Invalid Input!" << std::endl;
            parser.showHelp(1);
        }
        const double dt = args.last().toDouble(&conversionOk);
        if(!conversionOk){
            std::cout << "Invalid Input!" << std::endl;
            parser.showHelp(1);
        }
        const std::vector<double> wricker = rickerwavelet(fpeak,dt);
        for(size_t i=0;i<wricker.size();++i)
            std::cout << wricker[i] << std::endl;
        return 0;
    }
    


  • Thanks everyone for ur help, the question was solved.


  • Qt Champions 2018

    @Flavio-Mesquita Then please mark this thread as solved.



Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.