My programm reads values from a file and stores them in xArray and yArray. I tried to implement linear regression algorithm, it works but after certain point stops calculating correctly and error is getting bigger and bigger. Where is my error?
The desired f(x) : = 2x + 0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define SIZE 20 //size of the sample input array
#define iterations_number 100
#define PI 3.14159
double start_value = 5.5;
double xArray[SIZE] = { 0 };
double yArray[SIZE] = { 0 };
int array_size = sizeof(xArray) / sizeof(xArray[0]);
FILE* file;
FILE* file_xArray;
FILE* file_yArray;
FILE* sample;
void print_result(double b0, double b1, double error);
void calculate(); //calculate the best linear function
double calculateAngle(double x2, double y2, double x1, double y1);
void add_next_item_to_buffer_and_remove_last_item(double item, double* buffer);
void generate_first_sample_data_and_fill_xArray();
void generate_first_sample_data_and_fill_yArray();
void generate_first_sample_data();
void print_xArray();
void print_yArray();
void read_from_file_and_fill_xArray_and_yArray();
void reverseArray(int arr[], int start, int end);
void main(){
generate_first_sample_data();
read_from_file_and_fill_xArray_and_yArray();
reverseArray(xArray, 0, 2*SIZE);
reverseArray(yArray, 0, 2*SIZE);
calculate();
// print_xArray();
// print_yArray();
}
void add_next_item_to_buffer_and_remove_last_item(double item, double *buffer) {
for (int i = SIZE - 1; i > 0; i--) {
buffer[i] = buffer[i - 1];
}
buffer[0] = item;
}
void print_result(double b0, double b1, double error) {
printf("f(x) = %5f x + %5f\n", b1, b0);
printf("Error: %5f ", error);
}
void print_xArray() {
for (int i = 0; i < array_size; i++) {
printf("%f\n", xArray[i]);
}
}
void print_yArray() {
for (int i = 0; i <array_size; i++) {
printf("%f\n", yArray[i]);
}
}
void calculate() {
double y = 1;
double err = 5.0;
double b0 = 0.0;
double b1 = 0.0;
double alpha = 0.01; //error rate
double degree = 0;
double prediction_number = 0.0;
errno_t returnValue = fopen_s(&file, "data.txt", "w" );
fprintf(file, "SAMPLE_NO, ITERATION_NO, REF_VAL, MEASUREMENT, ERROR\n");
for (int i = 0; i < iterations_number; i++) {
int L = i % SIZE; // L - iteration length - number of samples per iteration
for (int j = 0; j < L; j++) {
y = b0 + b1 * xArray[j]; //y - predicted y value, xArray[i] - x value
}
err = y - yArray[L];
b0 = b0 - alpha * err;
b1 = b1 - alpha * err * xArray[L];
degree = calculateAngle(xArray[L], y, 0.0, 0.0);
print_result(b0, b1, err);
fprintf(file, "%.5f ", xArray[L]);
fprintf(file, "%d. ", i);
fprintf(file, "%.5f ", y);
fprintf(file, "%.5f ", degree);
fprintf(file, "%.5f\n", err);
}
fclose(file);
print_result(b0, b1, err);
}
double calculateAngle(double x2, double y2, double x1, double y1){
double deltaX = x2 - x1;
double deltaY = y2 - y1;
double rad = atan2(deltaY, deltaX); //radians
double degree = rad * (180 / PI);
return degree;
}
void generate_first_sample_data_and_fill_xArray() {
//first data randomly generated
errno_t returnValue = fopen_s(&file_xArray, "xArray.txt", "w");
for (int i = 0; i < array_size; i++) {
xArray[i] = 1.37 + i * 0.3;
fprintf(file_xArray, "%f\n", xArray[i]);
}
fclose(file_xArray);
}
void generate_first_sample_data_and_fill_yArray() {
//first data randomly generated
errno_t returnValue = fopen_s(&file_yArray, "yArray.txt", "w");
for (int i = 0; i < array_size; i++) {
yArray[i] = 1.02 + i * 2.0;
fprintf(file_yArray, "%f\n", yArray[i]);
}
fclose(file_yArray);
}
void generate_first_sample_data() {
errno_t returnValue = fopen_s(&sample, "sample.txt", "w");
for (int i = 0; i < array_size; i++) {
xArray[i] = i;
fprintf(sample, "%f ", xArray[i]);
yArray[i] = i * 2.0;
fprintf(sample, "%f\n", yArray[i]);
}
fclose(sample);
}
void read_from_file_and_fill_xArray_and_yArray() {
errno_t returnValue = fopen_s(&sample, "sample.txt", "r");
char line[SIZE];
const char* standard_white_space = " ";
char* xCoordinate= '\0';
char* yCoordinate= '\0';
while (fgets(line, sizeof line, sample) != NULL) {
// printf("%s\n", buffer);
// Token will point to the part before the
xCoordinate = strtok(line, standard_white_space);
add_next_item_to_buffer_and_remove_last_item(atof(xCoordinate), &xArray);
// Token will point to the part after the
yCoordinate = strtok(NULL, standard_white_space);
add_next_item_to_buffer_and_remove_last_item(atof(yCoordinate), &yArray);
}
fclose(sample);
}
//example of reading from file in format
//x y degree
void read_from_file() {
errno_t returnValue = fopen_s(&sample, "sample.txt", "r");
char line[sizeof(xArray)];
char* search1 = " ";
char* search2= " ";
char* token;
while (fgets(line, sizeof line, sample) != NULL) {
// printf("%s\n", buffer);
// Token will point to the part before the " "
token = strtok(line, search1);
add_next_item_to_buffer_and_remove_last_item(strtod(token, NULL), &xArray);
// Token will point to the part after the " "
token = strtok(search1, search2);
add_next_item_to_buffer_and_remove_last_item(strtod(token, NULL), &yArray);
// Token will point to the part at end of the line
token = strtok(NULL, search2);
//add_next_item_to_buffer_and_remove_last_item(strtod(token, NULL), °reeArray);
}
fclose(sample);
}
void reverseArray(int arr [], int start, int end)
{
if (start >= end)
return;
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
// Recursive Function calling
reverseArray(arr, start + 1, end - 1);
}
Given sample file |xCoordinate yCoordinate|
sample file
Output: output
Sometimes i get also this exception nullptrExceptrion
here
yCoordinate = strtok(NULL, standard_white_space);
add_next_item_to_buffer_and_remove_last_item(atof(yCoordinate), &yArray);
Related
I am using Dev C++ compiler to run my C code below. I have used _UADD assembly function to make it more optimized. But I am getting an undefined reference error for _UADD. I have only minimal background in assembly language. Can I use this assembly function _UADD to optimize my C code and compile in Dev C++? If so how?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <x86intrin.h>
#include <stdint.h>
#ifndef N1_8_H
#define N1_8_H
void refined_karatsuba_mul(int16_t* h, const int16_t* f, const int16_t* g, int n);
#endif
static void schoolbook_mul(int16_t* h, const int16_t* f, const int16_t* g, int n)
{
int16_t result;
int i,j;
for (i = 0; i < n; ++i) {
result = 0;
for (j = 0; j <= i; ++j) result = result+f[j]*g[i-j];
h[i] = result;
}
for (i = n; i < n+n-1; ++i) {
result = 0;
for (j = i-n+1; j < n; ++j) result = result+f[j]*g[i-j];
h[i] = result;
}
}
void refined_karatsuba_mul(int16_t* h, const int16_t* f, const int16_t* g, int n) {
const int16_t* f0 = f;
int16_t f01[n/2];
const int16_t* f1 = f + n/2;
const int16_t* g0 = g;
int16_t g01[n/2];
const int16_t* g1 = g + n/2;
uint32_t result;
for (int i = 0; i < n/2; i+=2) {
*(int32_t*)(&f01[i]) = __UADD16(*(int32_t*)(&f0[i]), *(int32_t*)(&f1[i])); // f01[i]= f0[i] + f1[i] and f01[i+1]= f0[i+1] + f1[i+1]
*(int32_t*)(&g01[i]) = __UADD16(*(int32_t*)(&g0[i]), *(int32_t*)(&g1[i])); // g01[i]= g0[i] + g1[i] and g01[i+1]= g0[i+1] + g1[i+1]
}
int16_t p1[n-1], p2[n-1], p3[n-1];
schoolbook_mul(p1, f0, g0, n/2);
schoolbook_mul(p2, f01, g01, n/2);
schoolbook_mul(p3, f1, g1, n/2);
for(int i = 0; i < n-1; i++) {
h[i] += p1[i];
h[i+n/2] += p2[i] - p1[i] - p3[i];
h[i+n] += p3[i];
}
}
int main(){
int16_t *f = malloc(8*sizeof(int16_t));
int16_t *g = malloc(8*sizeof(int16_t));
int16_t *h= calloc((2*8-1), sizeof(int16_t));
int i;
////////////////////////reading f and g
FILE *myFile;
myFile = fopen("inp8test", "r");
if (myFile == NULL){
printf("Error Reading File\n");
exit (0);}
for (i = 0; i < 8; i++){
fscanf(myFile, "%d", &f[i]);
f[i] = 0;
}
for (i = 0; i < 8; i++){
fscanf(myFile, "%d", &g[i] );
g[i] = 0;
}
fclose(myFile);
unsigned long long LastCycleCount = _rdtsc();
clock_t start = clock ();
for (i=0;i<999;i++){
refined_karatsuba_mul(h, f, g, 8);
memset(h, 0, sizeof(int16_t)*(2*8-1));
}
refined_karatsuba_mul(h, f, g, 8);
unsigned long long EndCycleCount = _rdtsc();
unsigned long long CyclesElapsed = EndCycleCount - LastCycleCount;
CyclesElapsed = CyclesElapsed/1000 ;
double Timelapsed=(clock()-start)/(double) CLOCKS_PER_SEC;
Timelapsed=Timelapsed/1000;
/////////////////////////////////////////////write on c_n1_8 file
FILE *outFile;
outFile = fopen("c_n1_8", "w");
if (outFile == NULL)
{
printf("Cannot Open File\n");
exit (0);
}
for (i = 0; i < 2*8-1; i++)
fprintf(outFile, "%d ", ((h[i])%3+3)%3 );
fclose(outFile);
/////////////////////////////////////////////////////////////printing on console
for( i=0; i<2*8-1; i++)
printf("%d ", ((h[i])%3+3)%3);
printf("\n\n\n");
printf("Cycles: %llu\n", CyclesElapsed);
printf("Multiplication Time:");
printf( "%f",Timelapsed);
printf("sec");
printf("\n \n ");
free(f);
free(g);
free(h);
return 0;
}
Trying to implement IFFT. If i set the input to this:
{0, 1, 0, 0, 0, 0, 0, 1}
it should transform it to a cosine with the lowest wave number. Instead i get this weird pattern:
bin 0: 2.000000 I 0.000000
bin 1: 0.000000 I 1.414214
bin 2: 0.000000 I 0.000000
bin 3: 0.000000 I 1.414214
bin 4: -2.000000 I 0.000000
bin 5: 0.000000 I -1.414214
bin 6: 0.000000 I 0.000000
bin 7: -0.000000 I -1.414214
I just took the FFT code and conjugated twiddle factors. Im told this should work fine. (besides the scaling factor) I don't understand what is wrong.
main.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "utils.h"
COMPLEX_FLOAT * coefficients;
void calculate_coefficients(int N)
{
COMPLEX_FLOAT * co = (COMPLEX_FLOAT *)malloc(N/2 * sizeof(COMPLEX_FLOAT));
coefficients = co;
for(int i = 0; i < N/2; i++)
{
co[i] = cf_exp(-2.0f*PI*((float)i)/((float)N));
}
}
COMPLEX_FLOAT* ifftr(COMPLEX_FLOAT* input, int N, int multiplier, int offset)
{
COMPLEX_FLOAT *output;
COMPLEX_FLOAT *E, *O;
output = (COMPLEX_FLOAT *)malloc(N * sizeof(COMPLEX_FLOAT));
if(N == 1)
{
output[0] = input[offset];
}
else
{
E = fftr(input, N/2, multiplier*2, offset);
O = fftr(input, N/2, multiplier*2, multiplier + offset);
for(int i = 0; i < N/2; i++)
{
int index = i * multiplier;
COMPLEX_FLOAT tmp = cmul(conjugate(coefficients[index]),O[i]);
output[i] = cadd(E[i], tmp);
output[i + N/2] = csub(E[i], tmp);
}
free(E);
free(O);
}
return output;
}
void ifft(COMPLEX_FLOAT* input, COMPLEX_FLOAT* output, int N)
{
COMPLEX_FLOAT * out;
calculate_coefficients(N);
out = ifftr(input,N,1,0);
for(int i = 0; i < N; i++)
{
output[i] = out[i];
}
free(out);
free(coefficients);
return;
}
int main()
{
int size = 8;
COMPLEX_FLOAT dummy[size];
COMPLEX_FLOAT frq[size];
for(int i = 0; i < size; i++)
{
frq[i].imag = 0;
if(i == 2)
{
frq[i].real = 1;
}
else if(size - i == 1)
{
frq[i].real = 1;
}
else
{
frq[i].real = 0;
}
}
ifft(frq, dummy, size);
for(int i = 0; i < size; i++)
{
printf("bin %d: %f\t I %f\n", i, dummy[i].real, dummy[i].imag);
}
return 0;
}
utils.c
#include "utils.h"
#include "math.h"
COMPLEX_FLOAT cadd(COMPLEX_FLOAT a, COMPLEX_FLOAT b)
{
COMPLEX_FLOAT out;
out.real = a.real + b.real;
out.imag = a.imag + b.imag;
return out;
}
COMPLEX_FLOAT csub(COMPLEX_FLOAT a, COMPLEX_FLOAT b)
{
COMPLEX_FLOAT out;
out.real = a.real - b.real;
out.imag = a.imag - b.imag;
return out;
}
COMPLEX_FLOAT cmul(COMPLEX_FLOAT a, COMPLEX_FLOAT b)
{
COMPLEX_FLOAT out;
out.real = a.real * b.real - a.imag * b.imag;
out.imag = a.real * b.imag + b.real * a.imag;
return out;
}
COMPLEX_FLOAT cf_exp(float a)
{
COMPLEX_FLOAT out;
out.real = (float)cos(a);
out.imag = (float)sin(a);
return out;
}
COMPLEX_FLOAT conjugate(COMPLEX_FLOAT a)
{
COMPLEX_FLOAT out;
out.real = a.real;
out.imag = -a.imag;
return out;
}
COMPLEX_FLOAT real_num(float n)
{
COMPLEX_FLOAT out;
out.real = n;
out.imag = 0;
return out;
}
I was calling the wrong recursive function fftr instead of ifftr
COMPLEX_FLOAT* ifftr(COMPLEX_FLOAT* input, int N, int multiplier, int offset)
{
COMPLEX_FLOAT *output;
COMPLEX_FLOAT *E, *O;
output = (COMPLEX_FLOAT *)malloc(N * sizeof(COMPLEX_FLOAT));
if(N == 1)
{
output[0] = input[offset];
}
else
{
E = ifftr(input, N/2, multiplier*2, offset);
O = ifftr(input, N/2, multiplier*2, multiplier + offset);
for(int i = 0; i < N/2; i++)
{
int index = i * multiplier;
COMPLEX_FLOAT tmp = cmul(conjugate(coefficients[index]),O[i]);
output[i] = cadd(E[i], tmp);
output[i + N/2] = csub(E[i], tmp);
}
free(E);
free(O);
}
return output;
}
I'm trying to parallelize my code, but i got errors. I need to calc a Cauchy problem (it's already done) but than i need to parallelize it using OpenMP lib.
I've tried to write some code with OpenMP, but it's not working.
I've created a struct to collect result.
struct Dots {
double par;
double x;
double y;
};
This is my target function with parameter.
int ode_func (double x, const double y[], double f[], void *params)
{
double mu = *(int *)params;
f[0] = x + 2 * y[0] / (1 + mu * mu);
return GSL_SUCCESS;
}
This is the main function. I currently didn't find a way how to create a array of arrays of struct, but this is not the main problem.
void calc_cauchy_problem(struct Dots ArrayOfDots[], double x_start, double x_end, double y_start,
int count) {
int dim = 1;
double x = x_start;
double y[1] = {y_start};
int mu = 5;
int param = 0;
gsl_odeiv2_system sys = {ode_func, NULL, dim, ¶m};
gsl_odeiv2_driver * d = gsl_odeiv2_driver_alloc_y_new (&sys,
gsl_odeiv2_step_rkf45, 1e-6, 1e-6, 0.0);
int status = 0;
#pragma omp parallel for shared(ArrayOfDots) private(sys, param, d, status)
for (int param = 1; param < mu; param++) {
gsl_odeiv2_system sys = {ode_func, NULL, dim, ¶m};
gsl_odeiv2_driver * d = gsl_odeiv2_driver_alloc_y_new (&sys,
gsl_odeiv2_step_rkf45, 1e-6, 1e-6, 0.0);
for (int i = 1; i <= count; i++)
{
double xi = x_start + i * (x_end - x_start) / count;
int status = gsl_odeiv2_driver_apply(d, &x, xi, y);
if (status != GSL_SUCCESS)
{
printf ("error, return value=%d\n", status);
break;
}
// ArrayOfDots[i].par = mu;
// ArrayOfDots[i].x = xi;
// ArrayOfDots[i].y = y[0];
}
gsl_odeiv2_driver_free (d);
}
}
The main
int main() {
double x_start = 0;
double x_end = 10;
double y_start = 0;
int count = 10;
struct Dots ArrayOfDots[count];
calc_cauchy_problem(ArrayOfDots, x_start, x_end, y_start, count);
return 0;
}
It's compiled successfully with this gcc main.c -o main -fopenmp -lgsl -std=gnu11 but when i launch it i got error
gsl: driver.c:354: ERROR: integration limits and/or step direction not consistent
Default GSL error handler invoked.
I think that the main problem with this #pragma omp parallel for shared(ArrayOfDots) private(sys, param, d, status) but i have no idea how to rewrite this in the other way.
Thanks for your responses.
UPD:
With Kaveh Vahedipour help my code partially start to work. It means that half of my for cycle start to work.
UPD UPD:
After another investigations i had the following code:
It's compile and run, but i got Process finished with exit code 4 and printf("Elapsed time = %f\n", omp_get_wtime() - start_time); don't print anything.
struct Dots {
double par;
double x;
double y;
};
int ode_func (double x, const double y[], double f[], void *params)
{
double mu = *(int *)params;
f[0] = (x + 2 * y[0]) / (1 + mu * mu);
return GSL_SUCCESS;
}
void calc_cauchy_problem(double x_start, double x_end, double y_start,
int count, int param1, int param2) {
int dim = 1;
double x = x_start;
double y[1] = {y_start};
int param = param1;
int j = 0;
int status = 0;
char filename[10];
#pragma omp parallel for private(param, status, x, y)
for (param = param1; param <= param2; param++) {
struct Dots ArrayOfDots[count];
gsl_odeiv2_system sys = {ode_func, NULL, dim, ¶m};
gsl_odeiv2_driver * d =
gsl_odeiv2_driver_alloc_y_new (&sys, gsl_odeiv2_step_rkf45, 1e-6, 1e-6, 0.0);
for (int i = 1; i <= count; i++) {
double xi = x_start + i * (x_end - x_start) / count;
int status = gsl_odeiv2_driver_apply(d, &x, xi, y);
if (status != GSL_SUCCESS)
{
printf ("error, return value=%d\n", status);
break;
}
ArrayOfDots[i].par = param;
ArrayOfDots[i].x = xi;
ArrayOfDots[i].y = y[0];
}
gsl_odeiv2_driver_free (d);
}
}
int main() {
double start_time = omp_get_wtime();
double x_start = 0;
double x_end = 10;
double y_start = 0;
const int count = 500;
int param1 = 1;
int param2 = 10;
calc_cauchy_problem(x_start, x_end, y_start, count, param1, param2);
printf("Elapsed time = %f\n", omp_get_wtime() - start_time);
return 0;
}
Add x to private loop vars: private(sys, param, d, status, x). Please get back to me, if you still experience issues.
void calc_cauchy_problem(double x_start, double x_end, double y_start,
int count, int param1, int param2) {
int dim = 1;
double x = x_start;
double y[1] = {y_start};
int param = param1;
int j = 0;
int status = 0;
char filename[10];
#pragma omp parallel for private(param, status, x, y)
for (param = param1; param <= param2; param++) {
struct Dots ArrayOfDots[count];
gsl_odeiv2_system sys = {ode_func, NULL, dim, ¶m};
gsl_odeiv2_driver * d =
gsl_odeiv2_driver_alloc_y_new (&sys, gsl_odeiv2_step_rkf45, 1e-6, 1e-6, 0.0);
for (int i = 1; i <= count; i++) {
double xi = x_start + i * (x_end - x_start) / count;
int status = gsl_odeiv2_driver_apply(d, &x, xi, y);
if (status != GSL_SUCCESS)
{
printf ("error, return value=%d\n", status);
break;
}
ArrayOfDots[i].par = param;
ArrayOfDots[i].x = xi;
ArrayOfDots[i].y = y[0];
}
//write_data_to_file(param, count, ArrayOfDots);
for (int i = 0; i < count; ++i) {
printf ("%d: %f, %f, %f\n", omp_get_thread_num(),
ArrayOfDots[i].par, ArrayOfDots[i].x, ArrayOfDots[i].y);
}
gsl_odeiv2_driver_free (d);
}
}
Seems like this version works fine. I think problem was with this struct Dots ArrayOfDots[count]; and when i try to push values to this struct.
ArrayOfDots[i].par = param;
ArrayOfDots[i].x = xi;
ArrayOfDots[i].y = y[0];
Here is the full code.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <omp.h>
// GSL lib includes
#include <gsl/gsl_sf_bessel.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_odeiv2.h>
int ode_func (double x, const double y[], double f[], void *params)
{
double mu = *(int *)params;
f[0] = (x + 2 * y[0]) / (1 + mu * mu);
return GSL_SUCCESS;
}
void calc_cauchy_problem(double x_start, double x_end, double y_start,
int count, int param1, int param2) {
#pragma omp parallel for
for(int param = param1; param < param2; param++) {
gsl_odeiv2_system sys = {ode_func, NULL, 1, ¶m};
gsl_odeiv2_driver * d =
gsl_odeiv2_driver_alloc_y_new (&sys, gsl_odeiv2_step_rk8pd,
1e-6, 1e-6, 0.0);
int i;
double x = x_start, x1 = x_end;
double y[1] = { y_start };
for (i = 1; i <= count; i++)
{
double xi = i * x1 / count;
int status = gsl_odeiv2_driver_apply (d, &x, xi, y);
if (status != GSL_SUCCESS)
{
printf ("error, return value=%d\n", status);
break;
}
// printf ("%d %d %.5e %.5e\n", omp_get_thread_num(), param, x, y[0]);
}
gsl_odeiv2_driver_free (d);
}
}
int main() {
double start_time = omp_get_wtime();
double x_start = 0;
double x_end = 10;
double y_start = 0;
const int count = 100000;
int param1 = 1;
int param2 = 20;
calc_cauchy_problem(x_start, x_end, y_start, count, param1, param2);
printf("Elapsed time = %f\n", omp_get_wtime() - start_time);
return 0;
}
Really thanks to Kaveh Vahedipour.
I am trying to create an image from a float * array. However, MagickConstituteImage constantly segfaults. Here is a summary of the relevant code (the problem occurs in the function writeRawImage()):
#include <stdio.h>
#include <stdlib.h>
#include <wand/MagickWand.h>
#define COLOR_MAX 65535.0
typedef struct {
float **px;
unsigned long width;
unsigned long height;
} RawPixels;
RawPixels getRawImage (char *path)
{
MagickWand *mw;
MagickBooleanType status;
PixelIterator *iter;
MagickPixelPacket pixel;
PixelWand **pixels;
RawPixels rp;
long x;
long y;
unsigned long width;
unsigned long count;
MagickWandGenesis();
mw = NewMagickWand();
status = MagickReadImage(mw, path);
rp.px = NULL;
if (status == MagickFalse) {
return rp;
}
iter = NewPixelIterator(mw);
if (iter == (PixelIterator *) NULL) {
return rp;
}
rp.width = 0;
rp.height = (unsigned long) MagickGetImageHeight(mw);
count = 0;
for (y = 0; y < rp.height; y++) {
pixels = PixelGetNextIteratorRow(iter, &width);
rp.width = (unsigned long) width;
if (rp.px == NULL) {
rp.px = malloc(sizeof(float *) * (width * rp.height + 1));
}
if (pixels == (PixelWand **) NULL) {
break;
}
for (x = 0; x < (long) width; x++) {
count++;
rp.px[count - 1] = malloc(sizeof(float) * 3);
PixelGetMagickColor(pixels[x], &pixel);
rp.px[count - 1][0] = pixel.red / COLOR_MAX;
rp.px[count - 1][1] = pixel.green / COLOR_MAX;
rp.px[count - 1][2] = pixel.blue / COLOR_MAX;
}
}
rp.px[count] = NULL;
return rp;
}
void freeRawImage (RawPixels rp)
{
for (int i = 0; rp.px[i] != NULL; i++) {
free(rp.px[i]);
}
free(rp.px);
}
void writeRawImage (RawPixels rp, char *path)
{
// This function is the one that gives me a headache.
// Basically, I take float **rp.px, which has the following structure
// at this point:
//
// {
// {float red, float green, float blue},
// {float red, float green, float blue},
// ...
// }
//
// Now, the documentation at https://www.imagemagick.org/api/magick-image.php#MagickConstituteImage
// says the following:
//
// "The pixel data must be in scanline order top-to-bottom"
//
// So up until the call to MagickConstituteImage() I am trying
// to restructure the data and write it into float *scanline
// to satisfy that requirement. However, once I call
// MagickConstituteImage(), my program segfaults.
MagickWand *mw;
float *scanline;
unsigned long pxcount;
for (pxcount = 0; rp.px[pxcount] != NULL; pxcount++);
pxcount *= 3;
scanline = malloc(sizeof(float) * pxcount);
pxcount = 0;
for (int i = 0; rp.px[i] != NULL; i++) {
for (int j = 0; j < 3; j++) {
scanline[pxcount++] = rp.px[i][j];
printf("%f\n", scanline[pxcount - 1]);
}
}
// This function causes a segfault
MagickConstituteImage(mw, rp.width, rp.height, "RGB", FloatPixel, scanline);
free(scanline);
}
int main ()
{
RawPixels rp;
if ((rp = getRawImage("samples/tiny-white.png")).px == NULL) {
fprintf(stderr, "ERROR: Failed to process image\n");
return 1;
}
// Some image processing using raw pixels here
writeRawImage(rp, "previews/preview.jpg");
freeRawImage(rp);
return 0;
}
You're not initializing
MagickWand *mw;
in the function writeRawImage(...) before using it in MagickConstituteImage(...)
I'm developing a program that read from CSV file and calculate score with a method "calculateMLpa". The method receive array of char and array of 10 float, and transform array of float in matrix 3x3. When read the position 3rd number from array, insert in matrix the 4th number and same for 6th number.
I.E.
array value[]={0.000000;123.814934;234.000000;100.000000;166.000000; 203.086639;383.000000;186.000000;338.000000;173.098419 }
array traj[]={"0-0";"0-1";"0-2";"1-0";"1-1";"1-2";"2-0";"2-1";"2-2"}
Xn_val[]={"0","1","2"}
When transform in matrix the result is:
123.814934 234.000000 166.000000
166.000000 203.086639 186.000000
186.000000 338.000000 173.098419
While the expected for [0;2] is 100.000000 and for [1;2]=383.000000, but when print the currently value of traj it's correct.
How can I fix this problem?
The code is all here:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <math.h>
#include <stdbool.h>
#include <ctype.h>
#define ARRAYSIZE(x) (sizeof(x)/sizeof(*(x)))
int csv_parse ( char *line, int size )
{
char *p;
char *dp;
int inquote;
int na;
int nTo_comma;
char prevc = ',';
char *list[256];
dp = NULL;
// inquote = 0;
na = 0;
prevc = ';';
nTo_comma=0;
for ( p = line; *p != '\n'; p++ )
{
nTo_comma++;
list[nTo_comma] = p;
if(*p == prevc)
{
printf("%s\t", list);
return na;
}
}
printf("\n");
return na;
}
double calculateMLpa(const char *Xn_val[], char *traj[], float value[], double alphaxixj, double tauxi, int sz, int dim) {
double mlx = 0;
double v;
double alphaxi;
char *state;
int i;
int p;
int j;
int k;
// int sz = sizeof(Xn_val) / sizeof(int);
// int dim = sizeof(traj) / sizeof(char);
double trns[sz][sz];
double m[sz];
char *trat="-";
// m[xi] values: the number of transitions leaving the state xi
printf("%d %d \n",sz,dim);
int cont=0;
for (i = 0; i <= sz; i++) {
m[i] = 0.0;
for (j = 0; j <= sz; j++) {
v = 0.0;
int newlength = strlen(Xn_val[i])+strlen(trat)+strlen(Xn_val[j])+1;
state = malloc(sizeof(char)*newlength);
if(state != NULL){
state[0] = '\0';
strcat(state,Xn_val[i]);
strcat(state,trat);
strcat(state,Xn_val[j]);
printf("%s ",state);
}else {
printf(stderr,"malloc failed!\n");
}
// for (k=0; k<=dim;++k){
if (traj[cont] != NULL ){
if (strcmp(traj[cont],state)==0){
v = value[cont+1];
printf("%f \n",v);
}
}
trns[i][j] = v;
printf("%f - \n",trns[i][j]);
if (strcmp(Xn_val[i],Xn_val[j])!=0)
m[i] = m[i] + v;
cont++;
}
}
for (i=0;i<=sz;++i){
for(j=0;j<=sz;++j){
printf("%f ",trns[i][j]);
}
printf("\n");
}
for (p=0;p<=sz;++p){
printf("%f - \n",m[p]);
}
printf("%f %f\n",trns[0][1],trns[0][2]);
alphaxi = alphaxixj * (((double) sz) - 1.0);
alphaxi = alphaxixj;
printf("%d ",sz);
for (i = 0; i <= sz; i++) {
for (j = 0; j <= sz; j++) {
// xi!=xj
if (strcmp(Xn_val[i], Xn_val[j])!=0) {
mlx = mlx + lgamma(alphaxixj + trns[i][j]) - lgamma(alphaxixj);
}
// xi
else {
mlx = mlx + lgamma(alphaxi) - lgamma(alphaxi + m[i]);
mlx = mlx + lgamma(alphaxi + m[i] + 1.0)+ (alphaxi + 1.0) * log(tauxi);
mlx = mlx - lgamma(alphaxi + 1.0)- (alphaxi + m[i] + 1.0) * log(tauxi + trns[i][j]);
}
}
}
return (mlx);
}
#define MAXFLDS 200 /* maximum possible number of fields */
#define MAXFLDSIZE 32 /* longest possible field + 1 = 31 byte field */
void parse(char *record, char *delim, char arr[][MAXFLDSIZE], int *fldcnt) {
char*p = strtok(record, delim);
int fld = 0;
while (p) {
strcpy(arr[fld], p);
fld++;
p = strtok('\0', delim);
}
*fldcnt = fld;
}
void main() {
printf("inizio\n");
FILE *pf;
int N=20;
bool first=true;
const char *a[]={"0","1","2"};
char *traject[]={"0-0","0-1","0-2","1-0","1-1","1-2","2-0","2-1","2-2"};
double bs=0;
char *trat="-";
pf=fopen("//home//user//prova.csv","r");
float array[10][10];
float *t;
char *str= "hello";
char *state;
t = (float *)malloc(N * sizeof(float));
int f=0;
if (pf)
{
size_t i, j, k;
char buffer[BUFSIZ], *ptr;
/*
* Read each line from the file.
*/
for ( i = 0; fgets(buffer, sizeof buffer, pf); ++i )
{
/*
* Parse the comma-separated values from each line into 'array'.
*/
for ( j = 0, ptr = buffer; j < ARRAYSIZE(*array); ++j, ++ptr )
{
array[i][j] = strtof(ptr, &ptr);
}
}
fclose(pf);}
else /* fopen() returned NULL */
{
perror(pf);
}
for(f=0; f<10; ++f){
if(f==0){}
else if(f==1 && array[f][8]==0)
array[f][8]=123.8149353;
t[f]=array[f][8];
//printf("%f \n",t[f]);
}
for (f=0;f<10; ++f){
printf("%f - ",t[f]);
}
//printf("%s, %s, %s \n",a[0],a[1],a[2]);
printf("start\n");
int sz = sizeof(a) / sizeof(char);
int dim = sizeof(traject) / sizeof(char);
printf("%d , %d \n",sz,dim);
bs=calculateMLpa(a,traject,t,1.0,0.1,sz,dim);
printf("done \n");
printf("%f ",bs);
}
EDIT
I try to pass array size
sz=sizeof(a)/sizeof(char)
dim = sizeof(traject) / sizeof(char);
but their value is 24 and 72 respectively, and the execution stops at 0-2 value 100.000000
Arrays passed to functions decay to pointers to the start of the array. So
#define ARRAYSIZE(x) (sizeof(x)/sizeof(*(x)))
Will not return anything meaningful when checking for its size in that case
To fix, pass the Array size as an additional Argument.
One major problem is that when you pass arrays to functions, they decay to pointers, and the sizeof trick you use to get the array size will not work.
You need to pass the actual array sizes as arguments.