Loop in basic C program - c

I can't find and resolve the error in this code.
I want Parray and Tarray to be filled with an iteration of the equation in the loop. I tried both for and while loop, but it seems that only the first member of the array is given proper value, and that value is lost by the beginning of a new cycle.
#include <stdio.h>
#include <stdlib.h>
int main() {
int i;
int j;
float dt,P_init,t_init,t_end;
dt = 0.03125;
P_init = 30;
t_init = 0;
t_end = 30;
int n_steps = 0;
n_steps = t_end/(float)dt;
int Parray[n_steps+1];
int Tarray[n_steps+1];
for (i=0; i<n_steps+1; i++)
{
Parray[i]=0;
Tarray[i]=0;
}
Parray[0] = P_init;
Tarray[0] = t_init;
int x;
float P,t,dpdt;
x = 1;
while (x < n_steps+1)
{
float s,d;
P = Parray[x-1];
t = Tarray[x-1];
dpdt = 0.7 * P * (1-(P/750)) - 20;
s = P + (dt * dpdt);
Parray[x] = s;
d = t + dt;
Tarray[x] = d;
x++;
printf("%f %f ",s,d);
}
return(0);
}

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i, j, x;
float dt, P_init, t_init, t_end, P, t, dpdt;
dt = 0.03125;
P_init = 30;
t_init = 0;
t_end = 30;
int n_steps = 0;
n_steps = t_end / (float)dt;
// using float arrays
float Parray[n_steps+1];
float Tarray[n_steps+1];
for (i = 0; i < n_steps+1; i++)
Parray[i] = 0;
for (j = 0; j < n_steps+1; j++)
Tarray[j] = 0;
Parray[0] = P_init;
Tarray[0] = t_init;
for (x = 1; x < n_steps + 1; x++) {
float s , d;
P = Parray[x-1];
t = Tarray[x-1];
dpdt = 0.7 * P * (1 - (P / 750)) - 20;
s = P + (dt * dpdt);
Parray[x] = s;
d = t + dt;
Tarray[x] = d;
printf("%f %f\n", s, d);
}
return(0);
}
I changed the int arrarys to float arrays.
What do you actually calculate here?

This line
dpdt = 0.7 * P * (1-(P/750)) - 20;
It seems to have a float value, therefore the array must be float type, and ALL inputs you put in the array must be in FLOAT type.
Change this:
int Parray[n_steps+1];
int Tarray[n_steps+1];
to
float Parray[n_steps+1];
float Tarray[n_steps+1];
and
P_init = 30;
t_init = 0;
t_end = 30;
All of them should be 30.0, 0.0, 30.0
Don't forget this too:
Parray[i]=0;
Tarray[i]=0;
Change it to 0.0
In short, C is bad at differentiate between types, so if you declare a float array, all inputs must be x.0, not only x where x is an integer.

Related

Translating matlab's AGC function to C

I am trying to translate the Automatic Gain Control block from Matlab's communications toolbox. Here is the documentation but the relevant parts are summarized below:
The block diagram
Where
And
This is the code I've written:
double AGC_Detector(int N, float complex* input, int ndx)
{
double samp = 0;
for(int i = ndx*N; i < (ndx+1)*(N-1); i++)
{
samp += cabs(input[i])*cabs(input[i]);
}
samp = samp/N;
return samp;
}
void use_AGC(float complex* input,
float complex* output,
double step,
double desired_pwr,
int avrg_len,
int max_pwr,
int len)
{
double z = 0;
double e = 0;
double g = 0;
double prev_g = 0;
double dtctr = 0;
for(int i = 0; i < len; i++)
{
dtctr = AGC_Detector(avrg_len,input,i);
z = dtctr * exp(2*prev_g);
e = desired_pwr - log(z);
g = prev_g + step*e;
if(g > max_pwr)
{
g = max_pwr;
}
prev_g = g;
output[i] = input[i] * exp(prev_g);
}
}
But I am not getting the same output I get for the same values in Matlab. What am I doing wrong?
Thank You!
Maybe it's not the only error but I've noticed, that the sum of the AGC Detector goes from ndx*N to (ndx+1)N-1 in the Matlab documentation, but in your C code it goes from
ndx*N to (ndx+1)(N-1)
I figured it out. Code below gives same output as matlab for a given set of complex data.
double AGC_Detector(double complex input, double* sum, double state[], unsigned int* idx, int N)
{
unsigned int first;
unsigned int nth;
double output;
double val = cabs(input)*cabs(input);
*sum += val;
output = (*sum)*(1.0/N);
*sum -= state[*idx-1];
if(*sum < 0.0){*sum = 0.0;}
state[*idx-1] = val;
first = *idx;
nth = first + 1;
if(nth < first){nth = 0xFFFFFFFF;}
*idx = nth;
if(*idx > N-1){*idx = 1;}
return output;
}
void use_AGC(double complex* input, double complex* output, double step, double desired_pwr, int avrg_len, int max_pwr, int len)
{
unsigned int idx = 1;
int filt_len = avrg_len-1;
double K = step;
double g = 0;
double sum = 0;
double dtctr = 0;
double filterState[filt_len];
for(int i = 0; i < filt_len; i++){filterState[i] = 0;}
for(int i = 0; i < avrg_len; i++)
{
dtctr = AGC_Detector(input[i], &sum, filterState, &idx, avrg_len);
output[i] = input[i] * exp(g);
dtctr = log(dtctr);
g += K*(desired_pwr - (dtctr + 2.0*g));
if(g > max_pwr){g = max_pwr;}
}
}

Perceptron in C fails to train

Trying to implement a perceptron in C, can't get it to train.
The output always just goes to zero and I don't know what’s wrong.
Although, I do suspect it might be either the delta function or me just incorrectly implementing the perceptron.
Thanks in advance to everyone who helps!
#include<stdio.h>
#define arrayLength(x) (sizeof(x) / sizeof((x)[0]))
typedef int bool;
enum { false, true };
int main(){
float trainInputs [2][2] = {{0.0f, 1.0f}, {0.0f, 0.0f}};
float trainOutputs [2][1] = {{1.0f}, {0.0f}};
int amontOfTrainData = 1;
float inputs [] = {0.0f, 1.1f};
float outputs [] = {0.0f};
float wights [(arrayLength(inputs) * arrayLength(outputs))] = {0.5f, 0.5f, 0.5f, 0.5f};
float learningRate = 0.01f;
float delta(float actual, float want, float wight){
float error = want - actual;
float out = error * learningRate * wight;
printf(":%.6f:\n", out);
return out;
}
// Run perceptron
void run(bool train){
int outputInc = 0;
int wightInc = 0;
while(outputInc < arrayLength(outputs)){
int inputInc = 0;
while(inputInc < arrayLength(inputs)){
if(train){
int x = 0;
while(x < amontOfTrainData){
outputs[outputInc] = trainInputs[x][inputInc] * wights[wightInc];
wights[wightInc] = delta(outputs[outputInc], trainOutputs[x][outputInc], wights[wightInc]);
x++;
}
}else{
outputs[outputInc] = inputs[inputInc] * wights[wightInc];
}
inputInc++;
wightInc++;
}
//printf("out[%i]: %.5f\n", outputInc, outputs[outputInc]);
outputInc++;
}
}
int b = 0;
while(b < 100){
run(true);
b++;
}
printf("-----------[ 100 LOOPS DONE ]-----------\n");
run(false);
return 0;
}
As error, learningRate and wight are less than 0, the expression error * learningRate * wight will tend to 0 too.
The delta should not be the new value for the weight, it is the amount of change, so instead of:
wights[wightInc] = delta(...);
Try:
wights[wightInc] += delta(...);
(Which source are you using for you perceptron formulas?)
I have applied all the changes and this is the final working code.
Thanks to everyone who helped me!
#include<stdio.h>
#include<stdbool.h>
#define arrayLength(x) (sizeof(x) / sizeof((x)[0]))
float trainInputs [2][2] = {{0.0f, 1.0f}, {0.0f, 0.0f}};
float trainOutputs [2][1] = {{1.0f}, {0.0f}};
int amontOfTrainData = 1;
float inputs [] = {1.0f, 1.0f};
float outputs [] = {0.0f};
float wights [(arrayLength(inputs) * arrayLength(outputs))] = {0.001f, 0.001f};
float learningRate = 0.1f;
float delta(float actual, float want, float wight)
{
float error = want - actual;
float out = error * learningRate * wight;
return out;
}
void run(bool train)
{
int outputInc = 0;
int wightInc = 0;
while(outputInc < arrayLength(outputs))
{
int inputInc = 0;
while(inputInc < arrayLength(inputs))
{
if(train)
{
int x = 0;
while(x < amontOfTrainData)
{
outputs[outputInc] = trainInputs[x][inputInc] * wights[wightInc];
wights[wightInc] += delta(outputs[outputInc], trainOutputs[x][outputInc], wights[wightInc]);
x++;
}
}
else
{
outputs[outputInc] = inputs[inputInc] * wights[wightInc];
}
inputInc++;
wightInc++;
}
printf("out[%i]: %.5f\n", outputInc, outputs[outputInc]);
outputInc++;
}
}
int main()
{
// Run neural network
int b = 0;
int loops = 500;
while(b < loops)
{
run(true);
b++;
}
printf("-----------[ %i LOOPS DONE ]-----------\n", loops);
run(false);
return 0;
}

How to generate array of random float numbers using functions in C

I already asked a question regarding a program. I got an answer but I have a new issue. The program I wrote is not working and I don't know why.
The function is working fine (I guess) but I want to be sure by printing the values of each element of the array and see if they are correct (I will need this for other purposes).
I tried with a simple for instruction for a printf, but the array seems to be empty. The problem may be related to the memory address of the value I want to print.
Please have a look, any advice will be welcome!
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
int * rand_gen(int N, float fl_value); // Function declaration
int main() // Main function
{
int N; // Declaration: Number of trials
printf("Number of trials: ");
scanf("%d", &N); // Asks for Number of trials
float alpha = 0.3;
float beta = 0.4;
float gamma = 0.5;
float delta = 0.6;
int i; // Index
int seed = time(NULL); // Random number generator seed (based on current time)
srand(seed);
// Populate arrays
float *bin_array_alpha[] = { rand_gen( N, alpha ) };
float *bin_array_beta[] = { rand_gen( N, beta ) };
float *bin_array_gamma[] = { rand_gen( N, gamma ) };
float *bin_array_delta[] = { rand_gen( N, delta ) };
// Here I would like to print the elements of the arrays, something like:
for ( i=0 ; i<N ; i++)
{
printf("\nbin_array_alpha[%d] = %f",i,bin_array_alpha[i]);
printf("\nbin_array_beta[%d] = %f",i,bin_array_beta[i]);
printf("\nbin_array_gamma[%d] = %f",i,bin_array_gamma[i]);
printf("\nbin_array_delta[%d] = %f",i,bin_array_delta[i]);
printf("\n");
}
// Free the memory
static const size_t m = sizeof(bin_array_alpha)/sizeof(bin_array_alpha[0]);
for ( size_t i = 0 ; i < m ; ++i )
{
free(bin_array_alpha[i]);
free(bin_array_beta[i]);
free(bin_array_gamma[i]);
free(bin_array_delta[i]);
bin_array_alpha[i] = NULL;
bin_array_beta[i] = NULL;
bin_array_gamma[i] = NULL;
bin_array_delta[i] = NULL;
}
printf("\n");
return(0);
}
// Function: generate an array populated by: array[j] = rand()*fl_value
int * rand_gen(int N, float fl_value)
{
int *array;
array = (int *)malloc(sizeof(float)*N);
if(array == NULL)
{
printf("\nRun out of memory!\n");
exit(1);
}
int j;
float x;
for( j = 0 ; j < N ; j++ )
{
x = rand(); // Generates a random number
x = x/RAND_MAX; // 0 < x < 1
x = x * fl_value;
array[j] = x; // array[j] = x * fl_value
}
return array;
}
The result is always the same (for example N=3):
bin_array_alpha[0] = 0.000000
bin_array_beta[0] = 0.000000
bin_array_gamma[0] = 0.000000
bin_array_delta[0] = 0.000000
bin_array_alpha[1] = 0.000000
bin_array_beta[1] = 0.000000
bin_array_gamma[1] = 0.000000
bin_array_delta[1] = 0.000000
bin_array_alpha[2] = 0.000000
bin_array_beta[2] = 0.000000
bin_array_gamma[2] = 0.000000
bin_array_delta[2] = 0.000000
Thank you so much again!
your problem is in the allocation of the arrays of float that you not simply confused with int but the technique of allocation is wrong:
float **rand_gen(int N, float fl_value)
{
float **array;
array = (float **)malloc(sizeof(float *) * N + 1);
if (array == NULL)
{
printf("\nRun out of memory!\n");
exit(1);
}
int i;
for (i = 0; i < N; i++)
{
array[i] = (int *)malloc(sizeof(float));
array[i][0] = 0;
}
array[N] = NULL;
int j;
float x;
for (j = 0; j < N; j++)
{
x = rand(); // Generates a random number
x = x / RAND_MAX; // 0 < x < 1
x = x * fl_value;
*(array[j]) = x; // array[j] = x * fl_value
}
return array;
}
An array of float is a pointer to a memory area where each element is a pointer to a float.
This means you have to correct the declaration:
float **rand_gen(int N, float fl_value); // Function declaration
and the usage in the main:
float **bin_array_alpha = rand_gen(N, alpha);
float **bin_array_beta = rand_gen(N, beta);
float **bin_array_gamma = rand_gen(N, gamma);
float **bin_array_delta = rand_gen(N, delta);
The same happens for the printf:
printf("\nbin_array_alpha[%d] = %f", i, *bin_array_alpha[i]);
Instead to free the memory you need to add the free not only of each float but also of the memory base:
free(bin_array_alpha

segment fault on programming C

I am tyring to make velocity Verlet method, by using C language.
I thought I made it good. However, there pops up 'Segmentation fault(core dumped)' whenever, I increase the size of the vector or array, x and y.
For the size n equal and less than 1e3, it's fine, but at the point of n = 1e4, the program gets error.
Please anybody help me on this.
Thank you.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double verlet(double t, double x)
{
double E = 0.252;
double B = 0.052;
double a = M_PI/2;
return -sin(x) + E*cos(t) + B*cos(2*t+a);
}
double pverlet(double(*f)(double, double), double dt, double t, double x, double y)
{
return x + dt*( y + (dt/2)*f(t, x));
}
double vverlet(double(*g)(double, double), double dt, double t, double x, double y)
{
return y + (dt/2) * g(t, x);
}
int main(void)
{
int i;
double t;
int n = 1e4;
double ti = 0, tf = 1e5, dt = (tf-ti)/n;
double *x = (double *) malloc(sizeof(double)*n);
double *y = (double *) malloc(sizeof(double)*2*n);
if (x == NULL)
{
printf("error allocating memory!\n");
return 1;
}
if (y == NULL)
{
printf("error allocating memory!\n");
return 1;
}
for (y[0] = 0, i = 1; i <2*n; i++)
{
y[i] = vverlet(verlet, dt, ti + dt*(i-1), x[i-1], y[i-1]);
}
for (x[0] = 0, i = 1; i < n; i++)
{
x[i] = pverlet(verlet, dt, ti + dt*(i-1), x[i-1], y[2*(i-1)]);
}
for (i = 0; i < n; i++)
{
t = ti + dt * i;
printf("%e %e %e\n", t, x[i], y[2*i]);
}
return 0;
free(x);
free(y);
}
for (y[0] = 0, i = 1; i <2*n; i++)
{
y[i] = vverlet(verlet, dt, ti + dt*(i-1), x[i-1], y[i-1]);
}
x is defined from 0 to n-1.

cast error and invalid conversion error

error: cast from 'void*' to 'unsigned int' loses precision
error: invalid conversion from 'unsigned int' to 'unsigned int**'
can u tell me how to properly cast this, i am getting error on this line:
color = (unsigned int)malloc(height*sizeof(unsigned int));
inside the main function.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
unsigned int width;
unsigned int height;
unsigned int **color = NULL;
bool file_write()
{
FILE *fractal = fopen("mandelbrot_imageSequential.ppm","w+");
if(fractal != NULL)
{
fprintf(fractal,"P6\n");
fprintf(fractal,"# %s\n", "Mandelbrot_imageSequential.ppm");
fprintf(fractal,"%d %d\n", height, width);
fprintf(fractal,"40\n");
int x = 0, y = 0;
unsigned int R = 0, G = 0, B = 0;
for(x = 0; x < width; ++x)
{
for(y = 0; y < height; ++y)
{
R = (color[y][x]*10);
G = 255-((color[y][x]*10));
B = ((color[y][x]*10)-150);
if(R == 10) R = 11;
if(G == 10) G = 11;
if(B == 10) B = 11;
putc(R, fractal);
putc(G, fractal);
putc(B, fractal);
}
}
fclose(fractal);
}
return true;
}
int method(int x, int y, double min_re, double max_re, double min_im, double max_im, int max_iterations)
{
double threshold = 4;
double x_factor = (max_re-min_re)/(width-1);
double y_factor = (max_im-min_im)/(height-1);
double c_im = max_im - y*y_factor;
double c_re = min_re + x*x_factor;
double Z_re = c_re, Z_im = c_im;
unsigned int col = 0;
for(unsigned n = 0; n < max_iterations; ++n)
{
double Z_re2 = Z_re*Z_re, Z_im2 = Z_im*Z_im;
if(Z_re2 + Z_im2 > threshold)
{
col = n;
break;
}
Z_im = 2 * Z_re * Z_im + c_im;
Z_re = Z_re2 - Z_im2 + c_re;
}
return col;
}
void method1(double min_re, double max_re, double min_im, double max_im, int max_iterations)
{
for(int x = 0; x < width; x++)
{
for(int y = 0; y < height; ++y)
{
int m1 = method(x,y,min_re,max_re,min_im,max_im,max_iterations);
if(m1)
{
color[x][y] = m1*50;
}
}
}
}
int main(int argc, char *argv[])
{
unsigned int max_iterations;
int x,y;
double threshold;
double min_re;
double max_re;
double min_im;
double max_im;
unsigned int NUM_OF_THREADS;
if(argc != 10)
{
printf("There is an error in the input given.\n");
return 0;
}
else
{
height = atoi(argv[1]);
width = atoi(argv[2]);
max_iterations = atoi(argv[3]);
min_re = atof(argv[4]);
max_re = atof(argv[5]);
min_im = atof(argv[6]);
max_im = atof(argv[7]);
threshold = atoi(argv[8]);
NUM_OF_THREADS = atoi(argv[9]);
}
color = (unsigned int)malloc(height*sizeof(unsigned int));
printf("height = %d\twidth = %d\tmaximum_iterations = %d\tminimum_x-value = %.2f\tmaximum_x-value = %.2f\tminimum_y-value = %.2f\tmaximum_y-value = %.2f\tthreshold_value = %.2f\tno. of threads = %d\t\n",height,width,max_iterations,min_re,max_re,min_im,max_im,threshold,NUM_OF_THREADS);
for(x = 0; x < height; x++)
{
color[x] = (unsigned int*)malloc(width*sizeof(unsigned int));
}
time_t ts,te;
time(&ts);
method1(min_re, max_re, min_im, max_im, max_iterations);
time(&te);
double diff = difftime(te,ts);
file_write();
printf("Total Time elapsed: %f\n",diff);
return 0;
}
Why are you casting the return value of malloc to an unsigned int?
First off, don't cast the return value of malloc in C. It is pointless and can actually hide the fact that you forgot to include . C is not C++ in this regard. A void* can be implicitly converted to any pointer type in C.
Secondly, malloc returns a pointer, and you have defined color as an unsigned int**... yet you attempt to assign an unsigned int as well as an unsigned int* to it. Obviously those are incompatible. Just drop the casts and use/declare the type properly.
color = (unsigned int**)malloc(height*sizeof(unsigned int*));
Shouldn't it be this?
You are trying to allocate array of pointers dynamically. So what you need to do is the following:
color = (unsigned int**)malloc(height*sizeof(unsigned int));
Rest of it is fine ...

Resources