Code:
#include <stdio.h>
#include <math.h>
#include <gng1106plplot.h>
#include <float.h>
#include <ctype.h>
#define NUM_POINTS 1000 // number of points
#define X_IX 0 // Row index for storing x values
#define FX_IX 1
#define TRUE 1
#define FALSE 0
#define EPSILON 1e-10
#define BINFILE "file.bin"
#define pi 3.1415926535897932384626433832795
typedef struct
{
double l; // starting time
double c; // ending time
double v; // velocity
double td; // time
double pc; // altitude
} INFO;
// Function Prototypes
void findRoot(INFO[], int , double * );
void plotFunc(INFO [], int,double *);
double func(INFO [],int , double);
double pfunc(double , int , double , INFO [] );
void plot(int numPoints, double points[][numPoints]);
double getMin(double *, int );
double getMax(double *, int );
int main()
{
int i=0;
int flag = FALSE;
int flag2;
int ans;
INFO data2[5];
FILE *fp2;
double root , R;
double check , check2;
double f;
char ans2;
if (access( BINFILE, 0 ) != -1 )
{
fp2 = fopen(BINFILE, "ab+");
printf("Do you want to choose previously inputted values? (y/n)\n");
fflush(stdin);
scanf("%c",&ans2);
if (ans2 == 'y')
flag = TRUE;
}
else fp2 = fopen(BINFILE, "ab+");
while(i < 5 && flag==FALSE)
{
do
{
flag2 = TRUE;
printf("Please enter the value for L:\n");
scanf("%lf",&data2[i].l);
printf("Please enter the value for C:\n");
scanf("%lf",&data2[i].c);
printf("Please enter the value for the battery voltage:\n");
scanf("%lf",&data2[i].v);
printf("Please enter the value for the dissipation time td:\n ");
scanf("%lf",&data2[i].td);
printf("Please enter the value for the percentage of the\n"
"original charge pc to reach within td\n");
scanf("%lf",&data2[i].pc);
R = (-2* data2[i].l * log(data2[i].pc))/data2[i].td;
check = 1/(data2[i].l*data2[i].c);
check = check - pow((R/(2*data2[i].l)),2) ;
check2 = sqrt(check);
f = check2/(2*pi);
if(check < 0)
{
flag2 = FALSE;
printf("Invalid input , Please enter a bigger value for td\n");
}
if(50/f < data2[i].td)
{
flag2 = FALSE;
printf("Frequency too high; plot may be distorted\n");
}
}while(flag2 == FALSE);
fwrite(&data2[i].l, sizeof(double), 1, fp2);
fwrite(&data2[i].c, sizeof(double), 1, fp2);
fwrite(&data2[i].v, sizeof(double), 1, fp2);
fwrite(&data2[i].td, sizeof(double), 1, fp2);
fwrite(&data2[i].pc, sizeof(double), 1, fp2);
//fwrite(&data2, sizeof(data2), 1 ,fp2);
i++;
printf("do you want to \n"
"1. enter a new set of values(max 5)\n"
"or\n"
"2.choose a saved set of values\n");
scanf("%d",&ans);
if (ans == 2)
flag = TRUE;
}
printf("which set of values do you want to use?\n");
scanf("%d",&ans);
rewind(fp2);
// compensate for zero element.
if ( ans-1 > 5)
{
printf("out of bounds\n");
return -1;
}
else
{
fread(data2, sizeof(data2), ans, fp2);
}
findRoot(data2,ans,&root);
printf("The value of the Resistor is %lf Ohms\n",root);
plotFunc(data2,ans,&root);
fclose(fp2);
return 0;
}
void findRoot(INFO data2[] , int sel , double *root)
{
sel = sel -1;
double upper = sqrt(4*data2[sel].l/data2[sel].c) ;
double lower = 0;
double x0 , x1 ;
x0=upper;
x1= lower;
if(func(data2,sel,x0)* func(data2,sel,x1) < 0)
{
do
{
*root = (x0+x1)/2;
if(func(data2,sel,*root)*func(data2,sel,x1) < 0 )
x0 = *root;
else x1 = *root;
}while(fabs(func(data2,sel,*root)*func(data2,sel,x1)) > EPSILON);
}
}
double func(INFO data[] ,int sel , double x)
{
double root;
root = exp(-(x*data[sel].td)/(2*data[sel].l));
root = root - data[sel].pc ;
return(root);
}
void plotFunc(INFO data2[], int sel, double *root)
{
int ix;
double inc;
double points[2][NUM_POINTS];
double x;
inc = data2[sel-1].td/1000;
for(ix = 0 ; ix < NUM_POINTS ; ix = ix+1)
{
points[X_IX][ix] = x; // Save x value
points[FX_IX][ix] = pfunc(x,sel-1,*root,data2); // Calculate and save f(x) value
x = x + inc; // update x value for next iteration
}
plot(NUM_POINTS, points);
}
double pfunc(double x,int index,double root ,INFO array2[] )
{
double fx;
fx = (array2[index].v*array2[index].c)*exp((-root*x)/(2*array2[index].l))*cos(sqrt((1/(array2[index].l*array2[index].c))-pow((root/(2*array2[index].l)),2))*x);
return(fx);
return(fx);
}
void plot(int numPoints ,double points[][numPoints] )
{
// Variable declaration
double minFx, maxFx; // Minimum and maximum values of f(x)
// Setup plot configuration
plsdev("wingcc"); // Sets device to wingcc - CodeBlocks compiler
// Initialize the plot
plinit();
// Configure the axis and labels
plwidth(3); // select the width of the pen
minFx = getMin(points[FX_IX], numPoints);
maxFx = getMax(points[FX_IX], numPoints);
plenv(points[X_IX][0],points[X_IX][numPoints-1],
minFx, maxFx, 0, 0);
plcol0(GREEN); // Select color for labels
pllab("x", "f(x)", "Plot of f(x) versus x");
// Plot the function.
plcol0(BLUE); // Color for plotting curve
plline(numPoints, points[X_IX], points[FX_IX]);
plend();
}
double getMin(double *array, int n)
{
int ix;
double min = array[0];
min = DBL_MAX;
for(ix = 1; ix < n; ix = ix +1)
if(min > array[ix]) min = array[ix];
return(min);
}
double getMax(double *array, int n)
{
int ix;
double max = array[0];
max = -DBL_MAX;
for(ix = 1; ix < n; ix = ix +1)
if(max < array[ix]) max = array[ix];
return(max);
}