How does this function change the parameter passed to it? - c

I seem to be lost with this Fourier Transform function. There's a sample program that I have but don't understand. The ggFFTworksp contains the data and fftFrameSize is simply framesize of the data. I don't understand how the function is supposed to put the FFT version of the data into the fftBuffer if there is no part in the code where fftBuffer is actually edited or manipulated. Thank you in advance!
The function call is this:
static float gFFTworksp[2*MAX_FRAME_LENGTH];
long fftFrameSize;
smbFft(gFFTworksp, fftFrameSize, -1);
The function in question is this:
void smbFft(float *fftBuffer, long fftFrameSize, long sign)
/*
FFT routine, (C)1996 S.M.Bernsee. Sign = -1 is FFT, 1 is iFFT (inverse)
Fills fftBuffer[0...2*fftFrameSize-1] with the Fourier transform of the
time domain data in fftBuffer[0...2*fftFrameSize-1]. The FFT array takes
and returns the cosine and sine parts in an interleaved manner, ie.
fftBuffer[0] = cosPart[0], fftBuffer[1] = sinPart[0], asf. fftFrameSize
must be a power of 2. It expects a complex input signal (see footnote 2),
ie. when working with 'common' audio signals our input signal has to be
passed as {in[0],0.,in[1],0.,in[2],0.,...} asf. In that case, the transform
of the frequencies of interest is in fftBuffer[0...fftFrameSize].
*/
{
float wr, wi, arg, *p1, *p2, temp;
float tr, ti, ur, ui, *p1r, *p1i, *p2r, *p2i;
long i, bitm, j, le, le2, k;
for (i = 2; i < 2*fftFrameSize-2; i += 2) {
for (bitm = 2, j = 0; bitm < 2*fftFrameSize; bitm <<= 1) {
if (i & bitm) j++;
j <<= 1;
}
if (i < j) {
p1 = fftBuffer+i; p2 = fftBuffer+j;
temp = *p1; *(p1++) = *p2;
*(p2++) = temp; temp = *p1;
*p1 = *p2; *p2 = temp;
}
}
for (k = 0, le = 2; k < (long)(log(fftFrameSize)/log(2.)+.5); k++) {
le <<= 1;
le2 = le>>1;
ur = 1.0;
ui = 0.0;
arg = M_PI / (le2>>1);
wr = cos(arg);
wi = sign*sin(arg);
for (j = 0; j < le2; j += 2) {
p1r = fftBuffer+j; p1i = p1r+1;
p2r = p1r+le2; p2i = p2r+1;
for (i = j; i < 2*fftFrameSize; i += le) {
tr = *p2r * ur - *p2i * ui;
ti = *p2r * ui + *p2i * ur;
*p2r = *p1r - tr; *p2i = *p1i - ti;
*p1r += tr; *p1i += ti;
p1r += le; p1i += le;
p2r += le; p2i += le;
}
tr = ur*wr - ui*wi;
ui = ur*wi + ui*wr;
ur = tr;
}
}
}

In the following line:
p1 = fftBuffer+i; p2 = fftBuffer+j;
p1 and p2 become pointers that point to the memory location of the fftBuffer array. And in these lines:
*(p2++) = temp; temp = *p1;
*p1 = *p2; *p2 = temp;
the values in these memory locations are being changed.

Related

Why am I getting a segfault in this genetic algorithm problem?

I'm trying to solve a CodeWars problem called "Training on Binary Genetic Algorithms." There is a fitness function that is preloaded. When the program is run, a test function creates a random 35-bit string and it uses my run function which is supposed to return the same 35-bit string. This string is supposed to be found using a genetic algorithm.
Here is my code:
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
typedef double fitness_t (const char *, ...);
extern fitness_t fitness;
void generate (size_t length, char * s)
{
for (size_t i = 0; i < length; i++)
s[i] = rand() % 2 + 48;
}
double sum(size_t n, double ar[n])
{
double sum = 0;
for (int i = 0; i < n; i++)
sum += ar[i];
return sum;
}
void select (int size, char* population[size], double fitnesses[size])
{
double probabilities[size]; // normalized to 1
double r; // random number
int s1, s2;
int i;
for (i = 0; i < size; i++)
probabilities[i] = fitnesses[i] / sum(size, fitnesses);
// select first chromosome
r = (double)(rand() % 1000000) / 1000000; // generates a random float between 0 and 1
for (i = 0; i < size && r > 0; i++)
r -= probabilities[i];
s1 = i;
// select second chromosome
s2 = s1;
while (s2 == s1) // ensures the two chromosomes aren't the same
{
r = (double)(rand() % 1000000) / 1000000; // generates a random float between 0 and 1
for (i = 0; i < size && r > 0; i++)
r -= probabilities[i];
s2 = i;
}
// places these two chromosomes on top
char * temp = population[0];
population[0] = population[s1];
population[s1] = temp;
temp = population[1];
population[1] = population[s2];
population[s2] = temp;
}
void crossover (size_t n, char* s1, char* s2)
{
int r = rand() % n; // select a random bit to cross over at
char temp;
for (size_t i = r; i < n; i++) // swap every bit from bit r to bit n
{
temp = s1[i];
s1[i] = s2[i];
s2[i] = temp;
}
}
void mutate (size_t n, char* s, double p)
{
double r;
for (size_t i = 0; i < n; i++) // for each bit
{
r = (double)(rand() % 1000000) / 1000000; // random float between 0 and 1
if (r <= p) // if random number is less than probability
{
if (s[i] == '1') s[i] = '0'; // swap 0s and 1s
else s[i] = '1';
}
}
}
void bubbleSortPop(int size, char * population[size], double fitnesses[size])
{
int i, j;
char * temp_chrome;
double temp_fitness;
for (i = 0; i < size - 1; i++)
// Last i elements are already in place
for (j = 0; j < size - i - 1; j++)
if (fitnesses[j] < fitnesses[j + 1])
{
temp_chrome = population[j];
population[j] = population[j+1];
population[j+1] = temp_chrome;
temp_fitness = fitnesses[j];
fitnesses[j] = fitnesses[j+1];
fitnesses[j+1] = temp_fitness;
}
}
// this function changes the population.
// select, crossover, mutate
void evolve(fitness_t f, size_t size, int length, char * population[size],
double fitnesses[size], double p_c, double p_m)
{
char * s1, * s2;
double f1, f2;
char * temp_pop[size+2];
double temp_fit[size+2];
int i;
double r;
// moves two selected parents to the top
select(size, population, fitnesses);
// begin reproduction process; duplicate the chromosomes
s1 = population[0];
s2 = population[1];
// crossover
r = (double)(rand() % 1000000) / 1000000; // random float between 0 and 1
if (r < p_c) // probability of crossing over
crossover(length, s1, s2); // commences with crossover
// mutate
mutate(length, s1, p_m);
mutate(length, s2, p_m);
// calculate fitnesses
f1 = f(s1);
f2 = f(s2);
// merge fitneses
// copy original fitnesses into temp_fit
for (i = 0; i < size; i++)
temp_fit[i] = fitnesses[i];
// add new fitnesses
temp_fit[size] = f1;
temp_fit[size+1] = f2;
// merge children into population
// copy original population into temp_pop
for (i = 0; i < size; i++)
temp_pop[i] = population[i];
// add two children to temp_pop
temp_pop[size] = s1;
temp_pop[size+1] = s2;
// sort fitnesses and population
bubbleSortPop(size+2, temp_pop, temp_fit);
// add first 100 elements of temp_pop and fit to population and fitnesses
for (i = 0; i < size; i++)
{
population[i] = temp_pop[i];
fitnesses[i] = temp_fit[i];
}
}
char* runN (fitness_t f, int length, double p_c, double p_m, size_t iterations) {
}
char* run (fitness_t f, int length, double p_c, double p_m)
{
size_t size = 100;
char * population[size];
double fitnesses[size];
size_t i;
int r;
srand(time(0));
// initialize population array
for (i = 0; i < size; i++)
population[i] = malloc((length+1) * sizeof(char));
// generate original population
for (i = 0; i < size; i++)
{
generate(length, population[i]);
fitnesses[i] = f(population[i]);
printf("[%2d] %s %lf\n", i, population[i], fitnesses[i]);
}
// evolve the population
for (i = 0; i < 10; i++)
evolve(f, size, length, population, fitnesses, p_c, p_m);
// print result
printf("\nAFTER EVOLUTION\n");
for (i = 0; i < size; i++) // generates original population
printf("[%2d] %s %lf\n", i, population[i], fitnesses[i]);
// store best chromosome and free memory
char ret[length+1];
strcpy(ret, population[0]);
for (i = 0; i < size; i++)
free(population[i]);
return ret;
}
The issue is when I run my code, it nearly always comes out with a segfault at some point while printing the contents of population and fitness.
At least these problems:
Attempting to print a non-string with "%s"
Code uses "%s" and passes population[i] as if it points to a string. population[i] does not point to a string as it does not certainly have a null character. Result undefined behavior (UB). Perhaps attempting to access beyond allocated memory.
// Undefined behavior: population[i] not a string
printf("[%2d] %s %lf\n", i, population[i], fitnesses[i]);
Set the null character.
generate(length, population[i]);
population[i][length] = '\0'; // Add this here or equivalent in `generate()`.
Many compiler warnings (20+)
Enable all compiler warnings and fix those.
I found the solution. It was all the places where I tried to copy a string by making a string pointer and assigning it the same address as the pointer I wanted to copy. For example, in 'select', when I tried to move the two strings to the top, I did
char * temp = population[0];
population[0] = population[s1];
population[s1] = temp;
temp = population[1];
population[1] = population[s2];
population[s2] = temp;
I changed this to using strcpy(). I made the same mistake in 'evolve' where I tried to duplicate the chromosomes by just copying their address into variables, rather than the strings themselves:
char * s1, * s2;
// begin reproduction process; duplicate the chromosomes
s1 = population[0];
s2 = population[1];
I changed it to this:
char s1[length+1], s2[length+1];
strcpy(s1, population[0]);
strcpy(s2, population[1]);
After I made this change the segfault went away. Thanks for all your answers.

Realloc couldn't allocate memory when used in loop

I am trying to implement Simpson 1/3 rule in C and facing a problem with using malloc inside a for loop.
My current implementation is
int integrateSimpson(Integrate *intereg)
{
int i, j, iLoop, last;
double *tempOne = (double *) malloc(sizeof(double) * 1);
double *tempTwo = (double *) malloc(sizeof(double) * 1);
double dx, sumOdd, sumEven, area;
double lowerLimit = intereg->lowerLimit;
double upperLimit = intereg->upperLimit;
int *intervals = intereg->intervals;
int nIntervals = intereg->nIntervals;
int method = intereg->method;
for(j = 0; j < nIntervals; j++ )
{
printf("Number of Intervals: %d",nIntervals);
for(iLoop = 0; iLoop < nIntervals; iLoop++){
printf("\nIntervals: %d", intervals[iLoop]);
}
tempOne = (double *) realloc(tempOne, sizeof(double) * intervals[j]);
tempTwo = (double *) realloc(tempTwo, sizeof(double) * intervals[j]);
if(tempTwo == NULL || tempOne == NULL)
{
TRACE("Could not realloc memory to temporary arrays");
return EXIT_FAILURE;
}
if(intervals[j] % 2 != 0)
{
TRACE("Found odd interval, adding 1 to make it even");
intervals[j] = intervals[j] + 1;
}
dx = (upperLimit - lowerLimit) / intervals[j];
for(i = 0; i <= intervals[j]; i++)
{
tempOne[i] = lowerLimit + i * dx;
tempTwo[i] = intereg->func(tempOne[i]);
}
sumOdd = 0;
sumEven = 0;
for(i = 1; i < intervals[j]; i++)
{
if(i % 2 == 1)
{
sumOdd += tempTwo[i];
}
else
{
sumEven += tempTwo[i];
}
}
printf("\nPassed %d time", j );
last = intervals[j] - 1;
area = dx / 3 * (tempTwo[0] + tempTwo[last] + 4 * sumOdd + 2 * sumEven);
intereg->areaUnderCurve[j] = area;
intereg->resultMatrix[method - 1][j] = intereg->areaUnderCurve[j];
}
free(tempOne);
tempOne = NULL;
free(tempTwo);
tempTwo = NULL;
return EXIT_SUCCESS;
}
I tried to debug this and found that for intervals = {2,8,16,64} the loop works fine for the first time even the realloc part but with the second iteration for some reason, realloc doesn't work and I get a segmentation fault. I tried to reproduce this problem in the following way but the code below works fine
int i;
double *temp;
/* Initial memory allocation */
temp = (double *) malloc(sizeof(double)*1);
/* Reallocating memory */
for(i = 0;i<10;i++)
{
temp = (double *) realloc(temp, sizeof(double)* i);
}
free(temp);
temp = NULL;
I know that realloc basically assigns a new memory at the same time frees the memory pointed by the pointer passed to it. But what is wrong that I am doing here?
Also is it a good way to use malloc with loops?
Any lead is appreciated!

how to store value of index of an array during while loop in C

int main()
{
int abc[2][2];
int i,j,q,r,u,k;
char *A = malloc(sizeof(*A));
abc[0][0] = 1;
abc[1][0] = 0;
abc[0][1] = 7;
abc[1][1] = 480;
do
{
if( abc[1][1]>abc[0][1])
{
q = floor((abc[1][1] - 1)/abc[0][1]);
r = abc[1][1] - q*abc[0][1];
abc[1][0] = q*abc[0][0] + abc[1][0];
abc[1][1] = r;
}
if( abc[0][1]>abc[1][1])
{
q = floor((abc[0][1] - 1)/abc[1][1]);
r = abc[0][1] - q*abc[1][1];
abc[0][0] = q*abc[1][0] + abc[0][0];
abc[0][1] = r;
}
u = abc[0][0];
A[k] = abc[1][0];
} while (abc[0][1]>1);
return 0;
}
I want to store each the values for the index - abc[1][0] in array A[] so that I cant use that array further but I'm stuck at storing all the values
If you want to record the value of abc[1][0] in the end of each loop, you can do like this:
int* A = malloc(1000 * sizeof(*A)); // Note: Room for 1000 values
k = 0;
....
....
do
{
....
....
if (k < 1000)
{
A[k] = abc[1][0];
++k;
}
} while (abc[0][1]>1);
// Print the recorded values
printf("Recorded %d values\n", k);
int t;
for (t = 0; t < k; ++t) printf("Value[%d]=%d\n", t, A[t]);
This will record the first 1000 values.
If you want to be able to record "any" number of values, you shall take a look at realloc so that you can assign more memory when you reach 1000

Open MP parallel for loop in C running in one thread

I have this part of a code which is reading a 2D array of structs, doing some math on them that putting the results into a second 2D array:
#pragma omp parallel for private (n, i, j) schedule(dynamic)
for(n = 0; n < frames_read; n++){
for (i = 0; i < atoms_total; i++)
{
for(j = 0; j < atoms_total; j++)
{
if (timestep_array[i][n].atom_id == timestep_array[j][m].atom_id)
{
// calculates the vector magnitude and stores it in the created array MSD
double temp1_x = timestep_array[i][n].normalized_x_position + timestep_array[i][n].x_box;
double temp2_x = timestep_array[j][n+1].normalized_x_position + timestep_array[j][n+1].x_box;
double temp3_x = temp2_x - temp1_x;
double temp4_x = temp3_x * box_bound_x;
double temp5_x = pow(temp4_x, 2);
double temp1_y = timestep_array[i][n].normalized_y_position + timestep_array[i][n].y_box;
double temp2_y = timestep_array[j][n+1].normalized_y_position + timestep_array[j][n+1].y_box;
double temp3_y = temp2_y - temp1_y;
double temp4_y = temp3_y * box_bound_y;
double temp5_y = pow(temp4_y, 2);
double temp1_z = timestep_array[i][n].normalized_z_position + timestep_array[i][n].z_box;
double temp2_z = timestep_array[j][n+1].normalized_z_position + timestep_array[j][n+1].z_box;
double temp3_z = temp2_z - temp1_z;
double temp4_z = temp3_z * box_bound_z;
double temp5_z = pow(temp4_z, 2);
double temp = temp5_x + temp5_y + temp5_z;
double temp2 = sqrt(temp);
int atom_number = timestep_array[i][n].atom_id;
MSD[atom_number][n].msd = sqrt(temp2);
MSD[atom_number][n].atom_type = timestep_array[i][n].atom_type;
MSD[atom_number][n].time_in_picoseconds = timestep_array[i][n].timestep / picoseconds;
}
}
}
}
I have tried so many combinations of the #pragma statement (including making many more of the variables private.) Nothing has resulted in the a.out file running more than one thread. What am I doing wrong?

Find mean,median without using arrays

How do i find mean , median of a set of numbers without using arrays in C?
Question is rather not the way to find mean or median but how to store a set of numbers and perform some operations on them if use of arrays is not allowed ?
A fun problem.
The key to to find a place to store all the numbers. Code could use a file, a linked list, etc. The below uses a linked list and recursion.
Leave it to OP for refinements about multiple modes or median when count is even.
typedef struct num_S {
struct num_S *prev;
double x;
} num_T;
void GetNum(num_T *prev) {
num_T current;
current.prev = prev;
// If new number found ...
if (scanf("%lf", &current.x) == 1) {
num_T *p = &current;
// Sort new entry into list
while (p->prev != NULL && p->x < p->prev->x) {
double t = p->x;
p->x = p->prev->x;
p->prev->x = t;
p = p->prev;
}
GetNum(&current);
// End of list -now process the list
} else {
unsigned ModeCount = 0;
double Mode = 0.0;
unsigned ModeCandidateCount = 0;
double ModeCandidate = 0.0 / 0.0;
unsigned Count = 0;
double SumX = 0.0;
double SumXX = 0.0;
num_T *p = current.prev;
while (p != NULL) {
Count++;
SumX += p->x;
SumXX += p->x * p->x;
if (p->x == ModeCandidate) {
ModeCandidateCount++;
} else {
ModeCandidateCount = 1;
ModeCandidate = p->x;
}
if (ModeCandidateCount > ModeCount) {
ModeCount = ModeCandidateCount;
Mode = p->x;
}
p = p->prev;
}
printf("Count = %u\n", Count);
if (Count > 0) {
printf("Mode = %lf Count %u\n", Mode, ModeCount);
printf("Mean = %lf\n", SumX / Count);
printf("STD = %lf\n", sqrt(Count * SumX - SumXX) / Count);
Count /= 2;
num_T *p = current.prev;
while (Count-- > 0) {
p = p->prev;
}
printf("Median = %lf\n", p->x);
}
fflush(stdout);
}
}
int main(void) {
GetNum(NULL);
return 0;
}
Input 4 3 4 2 4 1 EOF
Output:
Count = 6
Mode = 4.000000 Count 3
Mean = 3.000000
STD = 1.130388
Median = 3.000000
STD Ref: STD Rapid calculation methods

Resources