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 writing 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)fpeakdtpi;
beta = pow(alpha, 2.0);
wricker[i] = (1 - (beta2)) * 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_freqsampling_ratepi;
beta = pow(alpha, 2.0);
wricker[i] = polarity((1 - (beta2)) * 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.pi2)(f2)(t2)) * np.exp(-(np.pi2)(f2)(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???
Doing a bit of Debugging I found 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 signal meaning. I used qDebug only with the intention of showing the data on a terminal to make sure the calculation was working.
Thanks in advance.
C++ is much more like Python than C. Even though your C code was particularly convoluted, it still isn't as nice a C++ can be.
A complete example that even plots the data can be very, very simple. If that doesn't show the combined power of C++ and Qt, I hardly know what will :)
wavelet-plot-50690312.pro file
QT = charts
SOURCES = main.cpp
main.cpp
// https://github.com/KubaO/stackoverflown/tree/master/questions/wavelet-plot-50690312
#include <QtCharts>
#include <cmath>
const double pi = 3.14159265358979323846;
QVector<QPointF> ricker(double f, double length = 2.0, double dt = 0.001) {
size_t N = (length - dt/2.0)/dt;
QVector<QPointF> w(N);
for (size_t i = 0; i < N; ++i) {
double t = -length/2 + i*dt;
w[i].setX(t);
w[i].setY((1.0 - 2*pi*pi*f*f*t*t) * exp(-pi*pi*f*f*t*t));
}
return w;
}
QLineSeries *rickerSeries(double f) {
auto *series = new QLineSeries;
series->setName(QStringLiteral("Ricker Wavelet for f=%1").arg(f, 2));
series->replace(ricker(f));
return series;
}
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QChartView view;
view.chart()->addSeries(rickerSeries(1.0));
view.chart()->addSeries(rickerSeries(2.0));
view.chart()->createDefaultAxes();
view.setMinimumSize(800, 600);
view.show();
return app.exec();
}
Of course, this looks nice in C++. How about C? Let's pretend we had some C binding for Qt. Then it might look as follows:
// https://github.com/KubaO/stackoverflown/tree/master/questions/wavelet-plot-50690312/c-binding
#include "qc_binding.h"
#include <math.h>
#include <stddef.h>
#include <stdio.h>
const double pi = 3.14159265358979323846;
CQVector *ricker(double f, double length, double dt) {
scope_enter();
size_t N = (length - dt/2.0)/dt;
CQVector *vector = CQVector_size_(CQ_, CQPointF_type(), N);
CQPointF *const points = CQPointF_(CQVector_data_at(vector, 0));
for (size_t i = 0; i < N; ++i) {
double t = -length/2 + i*dt;
points[i].x = t;
points[i].y = (1.0 - 2*pi*pi*f*f*t*t) * exp(-pi*pi*f*f*t*t);
}
return scope_leave_ptr(vector);
}
CQLineSeries *rickerSeries(double f) {
scope_enter();
CQLineSeries *series = CQLineSeries_(CQ_);
CQLineSeries_setName(series, CQString_asprintf(CQ_, "Ricker Wavelet for f=%.2f", f));
CQLineSeries_replaceVector(series, ricker(f, 2.0, 0.001));
return scope_leave_ptr(series);
}
int main(int argc, char *argv[]) {
scope_enter();
CQApplication *app = CQApplication_(CQ_, &argc, argv);
CQChartView *view = CQChartView_(CQ_);
CQChart *chart = CQChartView_getChart(view);
CQChart_addLineSeries(chart, rickerSeries(1.0));
CQChart_addLineSeries(chart, rickerSeries(2.0));
CQChart_createDefaultAxes(chart);
CQWidget *view_ = CQWidget_cast(view);
CQWidget_setMinimumSize(view_, 800, 600);
CQWidget_show(view_);
return scope_leave_int(CQApplication_exec(app));
}
With a little bit of work, a C binding can be made that is about as easy to use as C++: scopes are tracked, RAII works, destructors get called when needed, values about to be returned are not destructed, etc.
Such a minimum binding, implementing all that's needed to run the code above, is available at https://github.com/KubaO/stackoverflown/tree/master/questions/wavelet-plot-50690312/c-binding.
Related
Hello I have a task in MPI. In this task I will implement a parallel image processing algorithm. This algorihm calculates the average of each pixel's value and its eight neighbors. You can think of an image as a 2-dimensional array of color values, that is, a matrix, the smoothing algorithm can be applied to all values of this matrix, that is, the pixels of an image.
The figure below shows the softening process of the midpoint and is the average of 8 neighbors after softening. 3x3 Smoothing (20+40+10+10+20+20+10+20+30)/9 = 20
My program applies a smoothing algorithm to the input image and then stores the results in a new image. So, I need to write a sequential program program.c that takes two inputs; first for the name of the input image and the second for the name of the output image. This section does not need to include any parallel processing.
I have two library for reading and writing: <stb_image.h> and <stb_image_write.h>
mpcc task.c -lm -o task_mpi
./task_mpi -n 2 input.jpg output.jpg
I tried to work on the program a bit, but I could not make fruitful progress.
Mycode:
#include <stdint.h>
#include <stdio.h>
#include <mpi.h>
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image.h"
#include "stb_image_write.h"
#define CHANNEL_NUM 1
int main(int argc,char* argv[]) {
int width, height, bpp, total,rgb;
MPI_Init(NULL,NULL);
int id ;
int size;
MPI_Comm_rank(MPI_COMM_WORLD,&id);
MPI_Comm_size(MPI_COMM_WORLD,&size);
int *img_mpi;
int local_image = (height/3)*width / size;
int* recv_buf = (int*) malloc(sizeof(int)*local_image);
int full_image[height*width];
// Reading the image
uint8_t* rgb_image = stbi_load(argv[1], &width, &height, &bpp, CHANNEL_NUM);
printf("Width: %d Height: %d \n",width,height);
for(int ii = 0; ii < height*width;ii++)
{
full_image[ii]=&rgb_image[ii];
}
MPI_Scatter(full_image, local_image ,MPI_INT, &recv_buf,local_image, MPI_INT, 1, MPI_COMM_WORLD);
if(id == 1)
{
for(int i=1;i<height;i++)
{
for(int j=1;j<width;j++)
{
total =
recv_buf,[(i-1)*width +(j-1)] +
recv_buf,[(i-1)*width +j] +
recv_buf,[(i-1)*width +(j+1)] +
recv_buf,[(i)*width +(j-1)] +
recv_buf,[i*width + j] +
recv_buf,[(i)*width +(j+1)] +
recv_buf,[(i+1)*width +(j-1)] +
recv_buf,[(i+1)*width +j] +
recv_buf,[(i+1)*width +(j+1)];
rgb = (total / 9);
recv_buf[i*width + j]= rgb;
}
}
}
MPI_Gather(&recv_buf, local_image ,MPI_INT, full_image, local_image, MPI_INT, 0, MPI_COMM_WORLD);
if(id == 0)
{
rgb_image = &recv_buf;
}
// Stoing the image
stbi_write_jpg(argv[2], width, height, CHANNEL_NUM, rgb_image, 100);
stbi_image_free(rgb_image);
MPI_Finalize();
return 0;
}
I have to create a code to create new vector which is created of range typed by user.
For ex: we start with 3 and end with 9. So i need crate vector forom 3 to 9 stepped by 0.25
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
float starts=0;
float ends=0;
float stepo = 0.25;
float tab[]={};
int startInt = 0;
int endInt = 0;
int counter = 0;
printf("Podaj poczatek:\n");// "Type starting int"
scanf("%d", &endInt);
printf("Podaj koniec:\n"); // "Type ending int"
scanf("%d", &startInt);
int diff = startInt - endInt;
printf("%d\n", diff);
starts= startInt;
ends= endInt;
for (int i = 0; i< (diff)*4; i++) {
tab[i]= ends;
printf("%f\n", tab[i]);**strong text**
ends = ends + stepo;
}
return 0;
}
I solved it by my own ;-) "float tab[]={};" it was a problem.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
float starts=0;
float ends=0;
float stepo = 0.25;
printf("Podaj poczatek:\n");
scanf("%f", &ends);
printf("Podaj koniec:\n");
scanf("%f", &starts);
float diff = starts - ends;
printf("%f\n", diff);
int tabSize = diff *4;
float tab[tabSize];
for (int i = 0; i<=diff*4; i++){
tab[i]= ends;
printf("%8.2f\n", tab[i]);
ends = ends + stepo;
}
return 0;
}
I have the following C function callThisFromR.c which I want to call from the R language,
#include <stdio.h>
#include <stdint.h>
#include <string.h>
void callThisFromR (
// some integer
int32_t integerFromR, // this is the length of the double vector `vec` to be passed again to R
// This is the R function passed to C: `getFuncFromR(vecLen, vec)`
double (* getFuncFromR) (
int32_t ,
double []
),
char inputString[] ,
int32_t inputStringLen
) {
printf("This is the integer passed from R: %d\n", integerFromR);
printf("This is the string passed from R: %s\n", inputString);
printf("This is the string length passed from R: %d\n", inputStringLen);
// Generate some double data to pass to R
double *vec;
vec = (double *) malloc( integerFromR * sizeof(*vec) );
for( int i=0; i<integerFromR; i++ ) {
vec[i] = (double) (i+1);
}
double result = getFuncFromR(integerFromR,vec);
printf("This is the result of the R callback function passed from R: %f\n", result );
}
This C function is supposed to be called from within R and expects to receive an int32 integer integerFromR, a string inputString and its length inputStringLen, as well as a callback function getFuncFromR from R. For example, here is the main.c C-equivalent of what I need to have in R,
#include <stdio.h>
#include <stdint.h>
#include <string.h>
double getFuncFromR (
int32_t vecLen,
double vec[]
)
{
double vecSum = 0.;
for(int i = 0; i < vecLen; i++){
vecSum += vec[i];
}
return vecSum;
}
int main(int argc, char *argv[])
{
char inputString[] = "ThisIsTheStringPassedFromR2C";
int32_t inputStringLen = strlen(inputString);
int32_t integerFromR = 3;
callThisFromR( integerFromR
, &getFuncFromR
, inputString
, inputStringLen
);
return 0;
}
Easy in C. But to call callThisFromR() C-function from R and pass an R function getFuncFromR() has so far been like a nightmare. How can I write the C wrapper function? My exhaustive web search for an answer (including the Rcpp and R-Foreign-Language-Extension documentation) have led to nothing.
I am running the exact same code in two ways: compiling it with the g++ compiler, and calling it from R with Rcpp. It turns out that it runs almost 4 times faster when I run it through R.
Why does this happen? Is it because the compiler used by Rcpp is different?
This is the code I'm running in c++:
#include <iostream>
#include <nlopt.hpp>
#include <time.h>
using namespace std;
int main()
{
//--------------------------------//
// Initialization //
//--------------------------------//
// Grid for x
const int nx = 60000;
float xgrid[nx];
const float xstep = 4 /(nx - 1);
float it = 0;
for(int i = 0; i < nx; i++){
xgrid[i] = it*xstep;
it++;
}
// Initialize value function V
size_t sizeV = nx*sizeof(float);
float *V;
V = (float *)malloc(sizeV);
//--------------------------------//
// Computation //
//--------------------------------//
// Variables for computation time
double t0 = clock();
double t = t0;
float utility;
float VV = pow(-10.0,5.0);
for(int ix = 0; ix<nx; ix++){
VV = pow(-10.0,5.0);
for(int ixp = 0; ixp < nx; ixp++){
utility = (xgrid[ix] + 1 - xgrid[ixp])*(xgrid[ix] + 1 - xgrid[ixp]);
if(utility >= VV){
VV = utility;
}
}
V[ix] = VV;
}
t = clock() - t0;
cout << "Time: " << ((float)t)/CLOCKS_PER_SEC << " seconds." << endl;
return 0;
}
To run it I use:
g++ Cpp_main.cpp -o Cpp_main
The code in Rcpp is:
#include <iostream>
#include <nlopt.hpp>
#include <time.h>
using namespace std;
// [[Rcpp::export]]
vector<double> value(int nx){
//--------------------------------//
// Grid creation //
//--------------------------------//
float xgrid[nx];
const float xstep = 4 /(nx - 1);
float it = 0;
for(int i = 0; i < nx; i++){
xgrid[i] = it*xstep;
it++;
}
// Initialize value function V
vector<double> V;
V.resize(nx);
//--------------------------------//
// Computation //
//--------------------------------//
// Variables for computation time
double t0 = clock();
double t = t0;
float utility;
float VV = pow(-10.0,5.0);
for(int ix = 0; ix<nx; ix++){
VV = pow(-10.0,5.0);
for(int ixp = 0; ixp < nx; ixp++){
utility = (xgrid[ix] + 1 - xgrid[ixp])*(xgrid[ix] + 1 - xgrid[ixp]);
if(utility >= VV){
VV = utility;
}
}
V[ix] = VV;
}
t = clock() - t0;
cout << "Time: " << ((float)t)/CLOCKS_PER_SEC << " seconds." << endl;
return V;
}
And I call it from R with:
library("Rcpp")
sourceCpp("Rcpp_main.cpp")
# Grid for x
nx = 60000;
V = value(nx);
The running time in c++ is twice the running time in Rcpp. Any clues why this happens?
Just looking your main() we get this:
edd#rob:/tmp/soQ$ g++ -o main main.cpp
edd#rob:/tmp/soQ$ ./main
Time: 8.42708 seconds.
edd#rob:/tmp/soQ$ g++ -o main -O3 -march=native main.cpp
edd#rob:/tmp/soQ$ ./main
Time: 1.59151 seconds.
edd#rob:/tmp/soQ$
That is already a factor of 5.3, and one of the weirdest examples I have seen in some time for the impact of -O3.
For R, I get about the same time as R defaults to using -O3 here too.
R> Rcpp::sourceCpp("/tmp/soQ/rcppfunction.cpp")
R> V <- value(60000)
Time: 1.65224 seconds.
R>
So no real mistery here. You used different options, and it mattered.
I have this C++ code from the web that computes for distance between two strings. Can someone help me convert this to OpenCL for parallelism? I'm having hard time learning OpenCL.
#include <stdio.h>
#include <math.h>
#include <string.h>
#define MIN(x,y) ((x) < (y) ? (x) : (y))
int main()
{
int d[100][100];
int i,j,m,n,temp,tracker;
char s[] = "Sanfoundry";
char t[] = "Education";
m = strlen(s);
n = strlen(t);
for(i=0;i<=m;i++)
d[0][i] = i;
for(j=0;j<=n;j++)
d[j][0] = j;
for (j=1;j<=m;j++)
{
for(i=1;i<=n;i++)
{
if(s[i-1] == t[j-1])
{
tracker = 0;
} else {
tracker = 1;
}
temp = MIN((d[i-1][j]+1),(d[i][j-1]+1));
d[i][j] = MIN(temp,(d[i-1][j-1]+tracker));
}
}
printf("the Levinstein distance is %d\n",d[n][m]);
return 0;
}
Specifically, what part of the code must be put in a kernel? Also, what memory objects needed to be created?
Thanks