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;
}
Related
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);
This question already has answers here:
Why do I get a segfault in C from declaring a large array on the stack?
(5 answers)
Closed 3 years ago.
I am learning C and trying new things to test what I can do. I have written code which produces a Mandelbrot set with a given resolution (RES) which is #define RES in the .h file. This works and produces good output for resolutions less than 321. For some reason when RES > 321 then the code no longer executes.
I am running using GCC and plotting the output using Gnuplot. I have tried debugging with a debugger however for RES > 321 the main function no longer gets run? I have added a print in the first line of main() to see and this doesn't get run. An executable is made and the program compiles with no errors?
#include <stdio.h>
#include <math.h>
#define MAX_DEPTH 100
#define RES 321
typedef struct complex_t {
double re;
double im;
} complex;
void init_complex_grid(complex complex_grid[RES][RES], double left, double right, double top, double bottom);
int converge(complex a);
complex add_complex(complex a, complex b);
complex square_complex(complex a);
double mag_complex(complex a);
void output_grid(unsigned int grid[RES][RES]);
int main(void) {
// printf("HERE\n");
int i, j;
unsigned int convergence_grid[RES][RES];
complex complex_grid[RES][RES];
init_complex_grid(complex_grid, -2.5, 1, 1, -1);
for (i = 0; i < RES; i++) {
for (j = 0; j < RES; j++) {
convergence_grid[i][j] = converge(complex_grid[i][j]);
}
}
output_grid(convergence_grid);
return 0;
}
void init_complex_grid(complex complex_grid[RES][RES],
double left, double right,
double top, double bottom) {
int i, j;
double restep = (top - bottom) / RES;
double imstep = (right - left) / RES;
for (i = 0; i < RES; i++) {
for (j = 0; j < RES; j++) {
complex_grid[i][j].re = left + j * imstep;
complex_grid[i][j].im = bottom + i * restep;
}
}
}
int converge(complex a) {
complex z = { 0, 0 };
int cnt = 0;
while (cnt <= MAX_DEPTH && mag_complex(z) <= 2) {
z = add_complex(square_complex(z), a);
cnt++;
}
return cnt;
}
complex add_complex(complex a, complex b) {
complex added = { a.re + b.re, a.im + b.im };
return added;
}
complex square_complex(complex a) {
complex b;
b.re = a.re * a.re - a.im * a.im;
b.im = 2 * a.re * b.im;
return b;
}
double mag_complex(complex a) {
return sqrt(a.re * a.re + a.im * a.im);
}
void output_grid(unsigned int grid[RES][RES]) {
FILE *f = fopen("mandelbrot.dat", "w");
int i, j;
for (i = 0; i < RES; i++) {
for (j = 0; j < RES; j++) {
fprintf(f, "%d ", grid[i][j]);
}
fprintf(f, "\n");
}
fclose(f);
printf("\nFILE CLOSED\n");
}
I also added the line printf("\nFILE CLOSED\n"); so I would know that the output had been written to the file but this does not get run either with RES > 321.
You are defining too much data with automatic storage in the main() function: either make the large arrays global, static or allocate them from the heap.
Here is a simple fix you can try:
int main(void) {
int i, j;
static unsigned int convergence_grid[RES][RES];
static complex complex_grid[RES][RES];
init_complex_grid(complex_grid, -2.5, 1, 1, -1);
for (i = 0; i < RES; i++) {
for (j = 0; j < RES; j++) {
convergence_grid[i][j] = converge(complex_grid[i][j]);
}
}
output_grid(convergence_grid);
return 0;
}
Here is an alternative using heap allocation:
int main(void) {
int i, j;
unsigned int (*convergence_grid)[RES] = calloc(sizeof(*convergence_grid), RES);
complex (*complex_grid)[RES] = calloc(sizeof(*complex_grid), RES);
if (!convergence_grid || !complex_grid) {
fprintf(stderr, "cannot allocate arrays\n");
return 1;
}
init_complex_grid(complex_grid, -2.5, 1, 1, -1);
for (i = 0; i < RES; i++) {
for (j = 0; j < RES; j++) {
convergence_grid[i][j] = converge(complex_grid[i][j]);
}
}
output_grid(convergence_grid);
free(complex_grid);
free(convergence_grid);
return 0;
}
I'm writing a C function to simulate a cache given an address trace. The function works as expected when compiled on my mac using gcc (really clang). gcc --version on my mac returns this:
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 8.1.0 (clang-802.0.42)
When I compile the same program on linux using gcc, the returns are way off, and eC & hC in my program (cache eviction counter and hit counter) are in the hundreds of thousands, when they should be below 10. When typing gcc --version on the linux machine, it returns this:
gcc (Ubuntu 4.9.3-8ubuntu2~14.04) 4.9.3
Here is the program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <limits.h>
#include <getopt.h>
#include "cachelab.h"
typedef struct{
int v;
int t;
int LRU;
} block;
typedef struct{
block *blocks;
} set;
typedef struct{
set *sets;
} cache;
void simulate(int s, int E, int b, char* file, int* hC, int* mC, int* eC)
{
int numSets = (1 << s);
char operation;
int address;
int size;
int curTag;
int curSet;
int maxLRU = 0;
int curLRU = 0;
int check = 0;
cache c;
set *sets = malloc(sizeof(set) * numSets);
c.sets = sets;
int i = 0;
while(i < numSets)
{
c.sets[i].blocks = malloc(sizeof(block) * E);
for (int j = 0; j < E; j++)
{
c.sets[i].blocks[j].v = 0;
c.sets[i].blocks[j].t = INT_MIN;
c.sets[i].blocks[j].LRU = 0;
}
i++;
}
FILE *f = fopen(file, "r");
while(fscanf(f," %c %x,%d", &operation, &address, &size) != EOF)
{
check = 0;
curTag = ((unsigned int) address) >> (s+b);
curSet = (address >> b) & ((1 << s) - 1);
for (int i = 0; i < E; i++)
{
c.sets[curSet].blocks[i].LRU++;
if(c.sets[curSet].blocks[i].LRU >= maxLRU)
{
maxLRU = c.sets[curSet].blocks[i].LRU;
curLRU = i;
}
if(curTag == c.sets[curSet].blocks[i].t)
{
*hC = *hC + 1;
if (operation == 'M')
{
*hC = *hC + 1;
}
c.sets[curSet].blocks[i].LRU = 0;
check = 1;
}
}
if(check == 0)
{
for(int i = 0; i < E; i++)
{
if(c.sets[curSet].blocks[i].v == 0)
{
*mC = *mC + 1;
if (operation == 'M')
{
*hC = *hC + 1;
}
c.sets[curSet].blocks[i].v = 1;
c.sets[curSet].blocks[i].LRU = 0;
c.sets[curSet].blocks[i].t = curTag;
check = 1;
break;
}
}
}
if(check == 0)
{
*eC = *eC + 1;
*mC = *mC + 1;
if (operation == 'M')
{
*hC = *hC + 1;
}
c.sets[curSet].blocks[curLRU].t = curTag;
c.sets[curSet].blocks[curLRU].v = 1;
c.sets[curSet].blocks[curLRU].LRU = 0;
}
}
}
int main(int argc, char** argv)
{
int hitCount, missCount, evictionCount;
int s, E, b;
char *file;
char opt;
while((opt = getopt(argc,argv,"v:h:s:E:b:t:")) != -1)
{
switch(opt){
case 'v':
break;
case 'h':
break;
case 's':
s = atoi(optarg);
break;
case 'E':
E = atoi(optarg);
break;
case 'b':
b = atoi(optarg);
break;
case 't':
file = optarg;
break;
default:
exit(1);
}
}
simulate(s, E, b, file, &hitCount, &missCount, &evictionCount);
printSummary(hitCount, missCount, evictionCount);
return 0;
}
EDIT:
I understand that this is due to a difference between clang and gcc. Does anyone have any information about how I can go about fixing this discrepancy?
Here is cachelab.c:
/*
* cachelab.c - Cache Lab helper functions
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "cachelab.h"
#include <time.h>
trans_func_t func_list[MAX_TRANS_FUNCS];
int func_counter = 0;
/*
* printSummary - Summarize the cache simulation statistics. Student cache simulators
* must call this function in order to be properly autograded.
*/
void printSummary(int hits, int misses, int evictions)
{
printf("hits:%d misses:%d evictions:%d\n", hits, misses, evictions);
FILE* output_fp = fopen(".csim_results", "w");
assert(output_fp);
fprintf(output_fp, "%d %d %d\n", hits, misses, evictions);
fclose(output_fp);
}
/*
* initMatrix - Initialize the given matrix
*/
void initMatrix(int M, int N, int A[N][M], int B[M][N])
{
int i, j;
srand(time(NULL));
for (i = 0; i < N; i++){
for (j = 0; j < M; j++){
// A[i][j] = i+j; /* The matrix created this way is symmetric */
A[i][j]=rand();
B[j][i]=rand();
}
}
}
void randMatrix(int M, int N, int A[N][M]) {
int i, j;
srand(time(NULL));
for (i = 0; i < N; i++){
for (j = 0; j < M; j++){
// A[i][j] = i+j; /* The matrix created this way is symmetric */
A[i][j]=rand();
}
}
}
/*
* correctTrans - baseline transpose function used to evaluate correctness
*/
void correctTrans(int M, int N, int A[N][M], int B[M][N])
{
int i, j, tmp;
for (i = 0; i < N; i++){
for (j = 0; j < M; j++){
tmp = A[i][j];
B[j][i] = tmp;
}
}
}
/*
* registerTransFunction - Add the given trans function into your list
* of functions to be tested
*/
void registerTransFunction(void (*trans)(int M, int N, int[N][M], int[M][N]),
char* desc)
{
func_list[func_counter].func_ptr = trans;
func_list[func_counter].description = desc;
func_list[func_counter].correct = 0;
func_list[func_counter].num_hits = 0;
func_list[func_counter].num_misses = 0;
func_list[func_counter].num_evictions =0;
func_counter++;
}
You forgot to initialize the counters and flags so they start at undefined values. The following lines:
int hitCount, missCount, evictionCount;
int s, E, b;
should be:
int hitCount = 0, missCount = 0, evictionCount = 0;
int s = 0, E = 0, b = 0;
It just happens that the initial values happen to be lower on the mac so you're not getting correct results on the mac either (at least not guaranteed since the initial value is undefined).
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.
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <time.h>
#define h 1
#define XY0 0
#define MAX_XY 5
#define N 2 //particles per subdomain
#define BLOCKS 4
#define a 1
#define b 1
float velocityX(float x, float y);
float velocityY(float x, float y);
int malloc2dfloat(float ***array, int length);
int main (int argc, char **argv)
{
typedef struct {
float xcoord;
float ycoord;
float velx;
float vely;
} particle;
int points= (int) floor((MAX_XY - XY0)/h) + 1;
int procsize = 2;
int myid, nproc;
MPI_Datatype particletype, oldtypes[1];
MPI_Aint offset[1], extent;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &nproc);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
int startElementX, startElementY, endElementX, endElementY;
particle* sub_pars = (particle*)malloc(sizeof(particle)*N);
offset[0] = 0;
int blockcounts[1];
blockcounts[0] = 4;
oldtypes[0] = MPI_FLOAT;
MPI_Type_struct(1, blockcounts, offset, oldtypes, &particletype);
MPI_Type_commit(&particletype);
particle* particles = (particle*)malloc(sizeof(particle) * N * procsize*procsize);
if (nproc != procsize*procsize){
printf("Must use np=4 -- split into 4 blocks");
MPI_Abort(MPI_COMM_WORLD,1);
}
srand(time(NULL)+myid);
if (myid == 0)
{
float mins[4];
startElementX = 0;
startElementY = 0;
endElementX = (points/procsize)-1;
endElementY = (points/procsize) -1;
}
else if (myid == 1)
{
startElementX = 0;
startElementY = (points/procsize);
endElementX = (points/procsize) -1;
endElementY = points - 1;
}
else if (myid == 2)
{
startElementX = (points/procsize);
startElementY = 0;
endElementX = points - 1;
endElementY = (points/procsize) -1;
}
else
{
startElementX = (points/procsize);
startElementY = (points/procsize);
endElementX = points-1;
endElementY = points-1;
}
int i;
float localmin;
float mag;
for (i=0; i<N; i++)
{
sub_pars[i].xcoord = ((startElementX + rand()/(RAND_MAX / (endElementX-startElementX+1)+1)))*h + XY0;
printf("%f\n", sub_pars[i].xcoord);
sub_pars[i].ycoord = ((startElementY + rand()/(RAND_MAX / (endElementY-startElementY+1)+1)))*h + XY0;
sub_pars[i].velx = velocityX(sub_pars[i].xcoord, sub_pars[i].ycoord);
sub_pars[i].vely = velocityY(sub_pars[i].xcoord, sub_pars[i].ycoord);
mag = sqrt(sub_pars[i].velx*sub_pars[i].velx + sub_pars[i].vely*sub_pars[i].vely);
if (i==0 || localmin > mag) localmin = mag;
}
printf("localmin of %d is %.2f \n", myid, localmin);
MPI_Allgather(&sub_pars, 1, particletype, particles ,1, particletype, MPI_COMM_WORLD);
MPI_Finalize();
if(myid == 0)
{
int k;
for (k=0; k<N*4; k++)
{
printf("test %.2f \n", particles[i].xcoord);
}
}
return 0;
}
float velocityX(float x, float y)
{
float temp = (a+(b*(y*y-x*x))/((x*x+y*y)*(x*x+y*y)));
return temp;
}
float velocityY(float x, float y)
{
float temp = (-1*(2*b*x*y)/((x*x+y*y)*(x*x+y*y)));
return temp;
}
It just returns the same value for all the particles, but I know they are being calculate correctly within each thread, so something is wrong with my MPI_Allgather, can someone please explain how it should look?
You have made a very common mistake: the & (address-of) operator in the first argument that you pass to MPI_Allgather is unnecessary. sub_pars is already a pointer and calling MPI_Allgather with &sub_pars passes a pointer to the pointer (a location somewhere in the stack frame of the main() routine) instead of pointer to the actual data.