trying to find the maximum difference between two arrays - c

edit: Apparently the variabledmaxdoesn't update with every loop.
I have 2 files that are scanned and inputted into 2 separate arrays but when I run the code to find the daily maximum difference between the same elements of the 2 arrays, the output reaches 107374208.000000. Here is my code down below.
void diff()
{
float ftemp[size], mtemp[size], diff[size], count = 1.0;
feb = fopen("feb.txt", "r");
mar = fopen("mar.txt", "r");
for(i = 1; i < size; i++)
{
fscanf(feb, "%f", &ftemp[i]);
fscanf(mar, "%f", &mtemp[i]);
dmax = (i * 3) - 3;
if((mtemp[dmax] - ftemp[dmax]) > count && (mtemp[dmax] - ftemp[dmax]) > 0)
{
count = mtemp[dmax] - ftemp[dmax];
}
}
printf("The highest temperature difference between March and February is %f.\n", count);
}
this is the daily temperatures for February
maximum minimum average
31.6 22.4 25.9
30.2 22.7 25.5
31.2 22.9 26.1
31.3 23.4 26.4
30.7 23.2 26.2
31.3 23.1 26.4
31.6 23.9 26.4
31.6 24.0 26.9
32.7 24.7 27.5
33.8 24.8 27.7
32.4 25.0 27.6
32.1 24.9 27.6
32.7 25.4 27.9
31.9 25.5 27.6
31.9 25.4 27.8
32.1 25.3 27.8
31.7 25.6 27.8
32.6 25.2 27.7
32.2 24.9 27.5
32.2 24.9 27.7
31.7 25.8 27.7
32.3 25.5 27.9
32.1 24.4 27.3
31.5 24.6 27.2
31.8 24.0 27.0
32.0 24.4 27.4
32.4 24.9 27.8
32.1 25.0 27.6
and this is the daily temperatures of March
maximum minimum average
32.7 25.1 27.7
33.8 24.8 28.0
32.9 24.7 27.6
32.9 25.0 27.8
32.9 25.0 27.8
33.0 23.8 27.5
32.6 24.2 27.6
32.8 24.8 27.9
32.0 24.2 27.6
32.3 24.9 27.8
33.6 25.0 28.1
33.4 25.6 28.3
33.8 24.7 28.3
34.1 25.2 28.6
32.7 25.9 28.6
28.2 23.6 25.9
30.7 24.3 26.4
32.7 24.9 27.5
32.5 25.4 27.5
33.6 25.9 27.6
33.1 25.3 27.7
31.0 25.0 27.5
32.8 24.2 27.9
33.0 24.7 28.1
33.2 25.2 28.4
34.0 25.7 28.8
34.4 25.8 29.1
32.7 26.2 28.6
33.3 26.5 28.5
32.3 25.8 28.5
33.0 26.6 28.8

The code doesn't compile because there's a bunch of undeclared variables like dmax and ftemp.
After fixing that...
The fopens are unchecked.
The files are assumed to be a certain size.
It's reading well past the initialized portion of the arrays.
fscanf is not checked.
fscanf is a bug generator.
Let's have a look at your loop.
for(i = 1; i < size; i++)
{
fscanf(feb, "%f", &ftemp[i]);
fscanf(mar, "%f", &mtemp[i]);
dmax = (i * 3) - 3;
if((mtemp[dmax] - ftemp[dmax]) > count && (mtemp[dmax] - ftemp[dmax]) > 0)
{
count = mtemp[dmax] - ftemp[dmax];
}
}
After the first iteration, dmax will always be larger than i (i = 0, dmax = 0; i = 1, dmax = 3; i = 2, dmax = 6). But the loop is only ever populated up to i. So mtemp[dmax] and ftemp[dmax] will never be populated when you try to use them. You'll get garbage.
I suspect you're assuming that fscanf(feb, "%f", &ftemp[i]) is scanning in a whole row of numbers. It's only scanning in one, just like you asked for. To do a whole row, you have to ask for that.
for( int i = 0; i < size; i += 3 ) {
fscanf(feb, "%f %f %f", &ftemp[i], &ftemp[i+1], &ftemp[i+2]);
fscanf(mar, "%f %f %f", &mtemp[i], &mtemp[i+1], &mtemp[i+2]);
...
}
Note that the loop starts at 0 because arrays start from 0. And it advances by 3, because we're reading in 3 at a time.
This still doesn't work. The first line of your files are all strings, not floating point numbers. fscanf doesn't skip ahead to find a match, if it doesn't match it stops. If you keep trying the same match it will keep trying to read from the same position over and over and over and over again. All your code is doing is trying to read in the first bytes of each file as a floating point number, failing, and then doing it again size times. ftemp[i] and mtemp[i] remain uninitialized so you get garbage.
This is why scanf and fscanf should be avoided. Instead, read in whole lines and process them with sscanf.
The arrays are also unnecessary, you're not doing anything with the previous values, you just need the current min and max.
Taking that all into account, and a few other things, I've rewritten it like this:
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#include <stdlib.h>
/* A little function to open files while checking it was
successful and giving a good error message if not */
FILE *open_file( const char *file, const char *mode ) {
FILE *fp = fopen(file, mode);
if( fp == NULL ) {
fprintf(
stderr,
"Could not open '%s' for '%s': %s\n",
file, mode, strerror(errno)
);
exit(1);
}
return fp;
}
/* Instead of using hard coded file names, they're passed in. */
/* Instead of hard coding the use of the diff, it's returned. */
/* I switched to doubles because that's what fabs() returns and
the extra accuracy can't hurt. */
double largest_max_temp_diff(const char *file1, const char* file2) {
FILE *feb = open_file(file1, "r");
FILE *mar = open_file(file2, "r");
char line1[1024];
char line2[1024];
/* Skip the header lines */
fgets(line1, 1024, feb);
fgets(line2, 1024, mar);
double max_diff = 0;
/* Loop infinitely, loop exit is handled using `break` */
while(1) {
/* Read in a line from each file.
Stop when we reach the end of either file. */
if( fgets(line1, 1024, feb) == NULL ) {
break;
}
if( fgets(line2, 1024, mar) == NULL ) {
break;
}
/* Read in just the first column, ignore the rest. */
/* Make sure the parsing was successful. */
double max1, max2;
if( sscanf(line1, "%lf %*lf %*lf", &max1) < 1 ) {
fprintf( stderr, "Could not understand '%s'", line1);
continue;
}
if( sscanf(line2, "%lf %*lf %*lf", &max2) < 1 ) {
fprintf( stderr, "Could not understand '%s'", line2);
continue;
}
/* Compare the diffs as absolute values */
double diff = max2 - max1;
if(fabs(diff) > fabs(max_diff)) {
max_diff = diff;
}
}
/* Return the max diff so it can be used as the caller likes */
return max_diff;
}
int main() {
/* Get the diff */
double diff = largest_max_temp_diff("feb.txt", "mar.txt");
/* Use it */
printf("The highest temperature difference between March and February is %f.\n", diff);
}
This new code now skips the header lines. It reads a line and parses it separately guaranteeing it won't get stuck. It parses one line at a time using sscanf only storing the max. It checks that the parsing succeeded.
It uses the absolute value to check for the maximum difference, because a difference of -4 is bigger than 3.
Finally, it returns that value for the caller to do what it wants with it. Calculating and printing (or any formatting) in the same function is a red flag; it makes functions inflexible and you wind up writing a lot of duplicate code.
It's not the best code, there's still a lot of duplication, but it's better and it checks itself. When working with files, you always have to check your assumptions.

Related

a void function to fill the array by converting integer to binary

int main(void)
{
/* Stop WDT */
MAP_WDT_A_holdTimer();
/* Selecting P1.2 and P1.3 in UART mode */
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
GPIO_PIN1 | GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);
/* Setting DCO to 12MHz */
CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_12);
/* Configuring UART Module */
MAP_UART_initModule(EUSCI_A0_BASE, &uartConfig);
/* Enable UART module */
MAP_UART_enableModule(EUSCI_A0_BASE);
/* Configuring GPIO2.4 as peripheral output for PWM and P6.7 for button
* interrupt */
MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2, GPIO_PIN4,
GPIO_PRIMARY_MODULE_FUNCTION);
redirect();
/* Configuring P1.0 as output */
MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);
/* Configuring Timer_A to have a period of approximately 500ms and
* an initial duty cycle of 10% of that (3200 ticks) */
//MAP_Interrupt_enableSleepOnIsrExit();
MAP_Interrupt_enableInterrupt(INT_TA0_0);
MAP_Timer_A_generatePWM(TIMER_A0_BASE,&pwmConfig);
MAP_Timer_A_clearInterruptFlag(TIMER_A0_BASE);
MAP_Timer_A_enableInterrupt(TIMER_A0_BASE);
MAP_Timer_A_enableCaptureCompareInterrupt
(TIMER_A0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_0);
/* Enabling MASTER interrupts */
MAP_Interrupt_enableMaster();
/* Sleeping when not in use */
while (1)
{
//MAP_PCM_gotoLPM0();
}
}
const int bit_length = 33;
int period;
int times[33];
int values[32];
x=598;
number_bit=10;
// this function - period,times,values
// x is the 32 bit integer , number_bit is how many bits in that integer
void int_To_Arr(uint32_t x,int number_bit){
int i = 0;
period = BIT_LENGTH * 67 ; // 15fps -> 1/15=66.67m
for (i = 0; i < number_bit ; i++) {
if (((x >> i) & 1) == 0) /* shift right by i-bits, check on/off */
values[i] = 1000; /* assign to values[i] based on result */
else
values[i] = 11000;
times[i] = BIT_LENGTH * i; /* set times[i] */
}
times[i] = BIT_LENGTH * i;
}
void TA0_0_IRQHandler(void)
{
int i,value;
MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A0_BASE,
TIMER_A_CAPTURECOMPARE_REGISTER_0);
time=time+1;
if(time>=period){
time=0;
MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);
}
for(i=0;times[i]!=-1;i++){
if(times[i]>time){
break;
}
value=values[i];
}
MAP_Timer_A_setCompareValue(TIMER_A0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_1, value);
}
So this function will take x (32-bit integer) and number_bit(how many bits in the integer) and will fill the array in the main. if the bit is 1 , values = 11000 which will turn on the led. if the bit is 0 ,values =1000 .Unfortunately, the LED doesnt blink or do anything. Before this I do it manually, yes the LED blinking.
int time=0;
const int BIT_LENGTH = 33;
int period;
int times[33]; //{x}
int values[32];//{y}
//new 1001010110
const int period=667; //15fps - bitlength*67
const int times[]={0,67,200,267,333,400,467,600,667,-1};
const int values[]={11000,1000,11000,1000,11000,1000,11000,1000};
If through the extended discussions we have had, you are seeking to fill the values array based on the number_bits in the uint32_t x value passed to your int_to_array function by shifting the value x to the right number_bits times and at each iteration determining whether that bit in x is 0 or 1 and setting values[i] = 1000 if the bit is 0 and to 11000 if the bit is 1, then you could do something like the following:
#define BIT_LENGTH 33 /* if you need a constant, define one (or more) */
#define FPS_MULT 33
...
/* fill values based on nbits bit-values in x,
* fill times based on BIT_LENGTH and index.
* note: CHAR_BIT defined in limits.h
* (defined as 8 for virtually all common systems)
*/
void int_to_array (uint32_t x, int nbits)
{
int i = 0; /* loop variable - can be declared in loop for C99+ */
period = BIT_LENGTH * FPS_MULT; // your 30fps-1/30=0.033
/* validate nbits <= 32 */
if (nbits > (int)(sizeof x * CHAR_BIT)) {
fprintf (stderr, "error: nbits out of range of uint32_t\n");
return;
}
for (i = 0; i < nbits; i++) {
if (((x >> i) & 1) == 0) /* shift right by i-bits, check on/off */
values[i] = 1000; /* assign to values[i] based on result */
else
values[i] = 11000;
times[i] = BIT_LENGTH * i; /* set times[i] */
}
times[i] = BIT_LENGTH * i; /* final times[BIT_LENGTH - 1] */
}
While I am still unclear where those values come from, based on our discussion, that should be what you are looking for. Otherwise, I'm still uncertain. note I have added a validation check to insure nbits cannot exceed 32 (the number of bits in x)
Validation Test
If you wanted to write a short bit of validation code for your function, you could just write a short program that passes the value provided on the command line as the first argument to your function as x (nbits won't change, it will always be sizeof x * CHAR_BIT). The following code passes the first argument to the function (passing 10 by default if no argument is given on the command line)
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <errno.h>
#include <limits.h>
#define BIT_LENGTH 33 /* if you need a constant, define one (or more) */
#define FPS_MULT 33
int period;
int times[BIT_LENGTH];
int values[BIT_LENGTH - 1];
/* fill values based on nbits bit-values in x,
* fill times based on BIT_LENGTH and index.
* note: CHAR_BIT defined in limits.h
* (defined as 8 for virtually all common systems)
*/
void int_to_array (uint32_t x, int nbits)
{
int i = 0; /* loop variable - can be declared in loop for C99+ */
period = BIT_LENGTH * FPS_MULT; // your 30fps-1/30=0.033
/* validate nbits <= 32 */
if (nbits > (int)(sizeof x * CHAR_BIT)) {
fprintf (stderr, "error: nbits out of range of uint32_t\n");
return;
}
for (i = 0; i < nbits; i++) {
if (((x >> i) & 1) == 0) /* shift right by i-bits, check on/off */
values[i] = 1000; /* assign to values[i] based on result */
else
values[i] = 11000;
times[i] = BIT_LENGTH * i; /* set times[i] */
}
times[i] = BIT_LENGTH * i; /* final times[BIT_LENGTH - 1] */
}
int main (int argc, char **argv) {
unsigned long tmp = argc > 1 ? strtoul (argv[1], NULL, 0) : 10;
uint32_t x;
int i, nbits = sizeof x * CHAR_BIT;
if (errno || tmp > UINT32_MAX) {
fprintf (stderr, "error: conversion error or value out of range.\n");
return 1;
}
x = (uint32_t)tmp;
int_to_array (x, nbits);
printf ("x: %u\n\nperiod: %d\n\n", x, period);
for (i = 0; i < nbits; i++)
printf ("values[%2d]: %5d times[%2d]: %5d\n",
i, values[i], i, times[i]);
printf (" times[%2d]: %5d\n", i, times[i]);
return 0;
}
(note: I tweaked the function by addition optional parenthesis to a check to get rid of a -pedantic signed/unsigned comparison warning and added a final times[i] = BIT_LENGTH * i; after the loop to handle times having 1 more element than values)
Example Test
Simple default value of 10 (1010)
$ ./bin/values_times
x: 10
period: 1089
values[ 0]: 1000 times[ 0]: 0
values[ 1]: 11000 times[ 1]: 33
values[ 2]: 1000 times[ 2]: 66
values[ 3]: 11000 times[ 3]: 99
values[ 4]: 1000 times[ 4]: 132
values[ 5]: 1000 times[ 5]: 165
values[ 6]: 1000 times[ 6]: 198
values[ 7]: 1000 times[ 7]: 231
values[ 8]: 1000 times[ 8]: 264
values[ 9]: 1000 times[ 9]: 297
values[10]: 1000 times[10]: 330
values[11]: 1000 times[11]: 363
values[12]: 1000 times[12]: 396
values[13]: 1000 times[13]: 429
values[14]: 1000 times[14]: 462
values[15]: 1000 times[15]: 495
values[16]: 1000 times[16]: 528
values[17]: 1000 times[17]: 561
values[18]: 1000 times[18]: 594
values[19]: 1000 times[19]: 627
values[20]: 1000 times[20]: 660
values[21]: 1000 times[21]: 693
values[22]: 1000 times[22]: 726
values[23]: 1000 times[23]: 759
values[24]: 1000 times[24]: 792
values[25]: 1000 times[25]: 825
values[26]: 1000 times[26]: 858
values[27]: 1000 times[27]: 891
values[28]: 1000 times[28]: 924
values[29]: 1000 times[29]: 957
values[30]: 1000 times[30]: 990
values[31]: 1000 times[31]: 1023
times[32]: 1056
or a larger value, 0xdeadbeef (11011110101011011011111011101111)
$ ./bin/values_times 0xdeadbeef
x: 3735928559
period: 1089
values[ 0]: 11000 times[ 0]: 0
values[ 1]: 11000 times[ 1]: 33
values[ 2]: 11000 times[ 2]: 66
values[ 3]: 11000 times[ 3]: 99
values[ 4]: 1000 times[ 4]: 132
values[ 5]: 11000 times[ 5]: 165
values[ 6]: 11000 times[ 6]: 198
values[ 7]: 11000 times[ 7]: 231
values[ 8]: 1000 times[ 8]: 264
values[ 9]: 11000 times[ 9]: 297
values[10]: 11000 times[10]: 330
values[11]: 11000 times[11]: 363
values[12]: 11000 times[12]: 396
values[13]: 11000 times[13]: 429
values[14]: 1000 times[14]: 462
values[15]: 11000 times[15]: 495
values[16]: 11000 times[16]: 528
values[17]: 1000 times[17]: 561
values[18]: 11000 times[18]: 594
values[19]: 11000 times[19]: 627
values[20]: 1000 times[20]: 660
values[21]: 11000 times[21]: 693
values[22]: 1000 times[22]: 726
values[23]: 11000 times[23]: 759
values[24]: 1000 times[24]: 792
values[25]: 11000 times[25]: 825
values[26]: 11000 times[26]: 858
values[27]: 11000 times[27]: 891
values[28]: 11000 times[28]: 924
values[29]: 1000 times[29]: 957
values[30]: 11000 times[30]: 990
values[31]: 11000 times[31]: 1023
times[32]: 1056
Look things over and let me know if you have further questions.
It seems you want to examine each bit of x and see if it is 1 or 0, using >> is correct however doing
x>>i; //x<<i
if(x&1==0){
will not work because x>>i just returns what the value of x shifted i bits is, it does not update the value of x. Instead, I would do the following
x = x >> 1;
if(x&1==0){
It will shift the value of x by one each time through the loop and then check the rightmost bit.
Also, your loop counter is incorrect, instead of
for(i=1;i<x;i++){
You most likely want
for(i = 1; i < number_bit; i++) {
Actually looking at this again, you special case setting times[0] and values[0] outside the loop, and then start your loop at 1, so if you want to keep the code structured like that, your loop counter must be
for(i = 1; i < number_bit - 1; i++) {
Though looking at the code, I see no reason to special case the setting of times[0] and values[0], if you examine it closely, you'll see you can loop from
for(i = 0; i < number_bit; i++) {
and include setting times[0] and values[0] within the loop. You would just have to do the shift AFTER setting values or use an if to not shift x when i is 0.

coulomb's law force calculation using c code

I am trying to write a simple program in C to calculate pairwise interaction (Coulomb force) between two chain of beads.Both chains contain 10 beads but one chain is positively charged and the other one is negatively charged. I am reading the x,y,z coordinates and the charge information from two files (Charge from 7th column of atom.psf and coordinates from 6th 7th and 8th columns of beads.pdb).
Here are the contents of the files:
atom.psf
20 !NATOM
1 A 1 CHN A A 1.000000 0.0000 0
2 A 1 CHN A A 1.000000 0.0000 0
3 A 1 CHN A A 1.000000 0.0000 0
4 A 1 CHN A A 1.000000 0.0000 0
5 A 1 CHN A A 1.000000 0.0000 0
6 A 1 CHN A A 1.000000 0.0000 0
7 A 1 CHN A A 1.000000 0.0000 0
8 A 1 CHN A A 1.000000 0.0000 0
9 A 1 CHN A A 1.000000 0.0000 0
10 A 1 CHN A A 1.000000 0.0000 0
11 A 2 CHN A A -1.000000 0.0000 0
12 A 2 CHN A A -1.000000 0.0000 0
13 A 2 CHN A A -1.000000 0.0000 0
14 A 2 CHN A A -1.000000 0.0000 0
15 A 2 CHN A A -1.000000 0.0000 0
16 A 2 CHN A A -1.000000 0.0000 0
17 A 2 CHN A A -1.000000 0.0000 0
18 A 2 CHN A A -1.000000 0.0000 0
19 A 2 CHN A A -1.000000 0.0000 0
20 A 2 CHN A A -1.000000 0.0000 0
18 !NBOND: bonds
1 2 2 3 3 4 4 5
5 6 6 7 7 8 8 9
9 10 11 12 12 13 13 14
14 15 15 16 16 17 17 18
18 19 19 20
beads.pdb
ATOM 1 A CHN 1 1.000 0.000 0.000 1.00 0.00 A
ATOM 2 A CHN 1 2.000 0.000 0.000 1.00 0.00 A
ATOM 3 A CHN 1 3.000 0.000 0.000 1.00 0.00 A
ATOM 4 A CHN 1 4.000 0.000 0.000 1.00 0.00 A
ATOM 5 A CHN 1 5.000 0.000 0.000 1.00 0.00 A
ATOM 6 A CHN 1 6.000 0.000 0.000 1.00 0.00 A
ATOM 7 A CHN 1 7.000 0.000 0.000 1.00 0.00 A
ATOM 8 A CHN 1 8.000 0.000 0.000 1.00 0.00 A
ATOM 9 A CHN 1 9.000 0.000 0.000 1.00 0.00 A
ATOM 10 A CHN 1 10.000 0.000 0.000 1.00 0.00 A
ATOM 11 A CHN 2 1.000 80.000 0.000 1.00 0.00 A
ATOM 12 A CHN 2 2.000 80.000 0.000 1.00 0.00 A
ATOM 13 A CHN 2 3.000 80.000 0.000 1.00 0.00 A
ATOM 14 A CHN 2 4.000 80.000 0.000 1.00 0.00 A
ATOM 15 A CHN 2 5.000 80.000 0.000 1.00 0.00 A
ATOM 16 A CHN 2 6.000 80.000 0.000 1.00 0.00 A
ATOM 17 A CHN 2 7.000 80.000 0.000 1.00 0.00 A
ATOM 18 A CHN 2 8.000 80.000 0.000 1.00 0.00 A
ATOM 19 A CHN 2 9.000 80.000 0.000 1.00 0.00 A
ATOM 20 A CHN 2 10.000 80.000 0.000 1.00 0.00 A
I am having trouble with my final output. At every timestep (t=0 to 100), I need to write the coordinates of 20 atoms. My trial code is given below.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define Epsilon0 8.85e-12 // Permittivity of free space (C^2/(N m^2))
#define Constant (1/(4*M_PI*Epsilon0)) // Useful constant
#define gamma 100.0
#define ROW 20
int row, col, j, t;
float x[20], y[20], z[20], q[20], dx, dy, dz, R, Fx, Fy, Fz, F, v, shift;
int main()
{
FILE *psf=fopen("atom.psf", "r");
FILE *pdb=fopen("beads.pdb", "r");
FILE *fout=fopen("out.txt", "a");
FILE *fout2=fopen("coord.dump", "a");
fprintf(fout2, "ITEM: TIMESTEP\n 100\n");
fprintf(fout2, "ITEM: NUMBER OF ATOMS\n 20\n");
fprintf(fout2, "ITEM: ATOMS id type x y z\n");
char buffer[1024];
fgets(buffer, 1024, psf);
int i = 0;
for(i=0 ; (i<ROW) && (psf != NULL); i++)
{
fscanf (psf,"%*8d%*4s%*4d%*6s%*5s%*6s%11f%*14f%*12d", &q[i]);
fscanf (pdb,"%*4s%*7d%*5s%*4s%*6d%12f%8f%8f%*6f%*6f%*9s", &x[i], &y[i], &z[i]);
}
for (t=0; t<100; t++)
{
//F = 0.0;
v = F/gamma;
shift = v*t;
x[i] = x[i] + shift;
y[i] = y[i] + shift;
z[i] = z[i] + shift;
for(i=0; i<ROW; i++)
{
Fx = Fy = Fz = F = 0.0;
// Loop over other charges to compute force on this charge
for (j=0 ; j<ROW ; j++)
{
//simply skip this itearation
if(i == j)
continue;
// Compute the components of vector distance between two charges
dx = x[i] - x[j];
dy = y[i] - y[j];
dz = z[i] - z[j];
R = sqrt(dx*dx + dy*dy + dz*dz);
// Compute the x and y components of the force between
// these two charges using Coulomb's law
Fx += Constant*q[i]*q[j]*dx/(R*R*R);
Fy += Constant*q[i]*q[j]*dy/(R*R*R);
Fz += Constant*q[i]*q[j]*dz/(R*R*R);
}
F = sqrt(Fx*Fx + Fy*Fy + Fz*Fz);
fprintf(fout, "%d %3.3g %3.3g %3.3g %3.3g\n", i+1, Fx, Fy, Fz, F);
//fprintf(fout2, "%d %3.3g %3.3g %3.3g\n", i+1, x[i], y[i], z[i]);
}
fprintf(fout2, "%d %3.3g %3.3g %3.3g\n", i, x[i], y[i], z[i]);
}
}
This is probably a situation where instead of attempting to keep track of numerous separate arrays containing various information, life can be made a lot easier if you simply create a struct that captures the needed information for each bead and then create a single array of struct. For example, you want to capture the x,y,z position, charge, and component forces acting on each bead. (I included the total force as well, but that is optional). Your struct for each bead (I called it beads) could be as simple as:
typedef struct {
float x, y, z, chrg, fx, fy, fz, f;
} beads;
In your code, you simply create an array of beads (one for each bead you need information on). For example, creating an array of beads with 20 elements, you could do something like the following:
#define Eo 8.85e-12F
#define KEair (1/(4*M_PI*Eo))
enum { NATM = 20, MAXL = 128 }; /* constants for number of beads/line len */
...
beads atoms[NATM] = {{ .x = 0.0 }};
Now we have an array of struct called atoms to store information in. You can read information from each of your files and store the x, y, z positions for each bead as well as the charge. Then you can compute the force acting on each bead by computing the force due to every other bead and summing the information in the remaining force component and total members of each struct. You may do something like:
for (i = 0; i < NATM; i++) { /* for each bead */
for (size_t j = 0; j < NATM; j++) { /* compute force from every other */
if (i == j) continue; /* excluding itself */
float dx = atoms[j].x - atoms[i].x, /* calculate component distances */
dy = atoms[j].y - atoms[i].y,
dz = atoms[j].z - atoms[i].z,
d = sqrt (dx * dx + dy * dy + dz * dz); /* total distance */
/* compute component and total forces acting on each bead (sum) */
atoms[i].fx += (KEair * atoms[i].chrg *atoms[j].chrg * dx)/(d * d * d);
atoms[i].fy += (KEair * atoms[i].chrg *atoms[j].chrg * dy)/(d * d * d);
atoms[i].fz += (KEair * atoms[i].chrg *atoms[j].chrg * dz)/(d * d * d);
atoms[i].f += (KEair * atoms[i].chrg *atoms[j].chrg)/(d * d);
}
}
(you can confirm the approach to the sum at System of discrete charges)
Putting it altogether, you could do something like the following:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define Eo 8.85e-12F
#define KEair (1/(4*M_PI*Eo))
enum { NATM = 20, MAXL = 128 };
typedef struct {
float x, y, z, chrg, fx, fy, fz, f;
} beads;
FILE *xfopen (const char *fn, const char *mode);
float sqrt_fisr (float x);
int main (int argc, char **argv) {
beads atoms[NATM] = {{ .x = 0.0 }};
size_t i;
char buf[MAXL] = ""; /* open/read atom.psf */
FILE *fp = xfopen (argc > 1 ? argv[1] : "dat/atom.psf", "r");
fgets (buf, MAXL, fp); /* read/discard 1st line */
for (i = 0; i < NATM && fgets (buf, MAXL, fp); i++) { /* read/parse data */
if (sscanf (buf, "%*s %*s %*s %*s %*s %*s %f", &atoms[i].chrg) != 1) {
fprintf (stderr, "error: read of charge failed, atom[%zu].\n", i);
return 1;
}
}
fclose (fp);
if (i != NATM) { /* validate NATM lines read */
fprintf (stderr, "error: only '%zu' charge values read.\n", i);
return 1;
}
/* open/read beads.pdb */
fp = xfopen (argc > 2 ? argv[2] : "dat/beads.pdb", "r");
for (i = 0; i < NATM && fgets (buf, MAXL, fp); i++) { /* read/parse data */
if (sscanf (buf, "%*s %*s %*s %*s %*s %f %f %f", &atoms[i].x,
&atoms[i].y, &atoms[i].z) != 3) {
fprintf (stderr, "error: read of position failed, atom[%zu].\n", i);
return 1;
}
}
fclose (fp);
if (i != NATM) { /* validate NATM lines read */
fprintf (stderr, "error: only '%zu' position values read.\n", i);
return 1;
}
for (i = 0; i < NATM; i++) { /* for each bead */
for (size_t j = 0; j < NATM; j++) { /* compute force from every other */
if (i == j) continue; /* excluding itself */
float dx = atoms[j].x - atoms[i].x, /* calculate component distances */
dy = atoms[j].y - atoms[i].y,
dz = atoms[j].z - atoms[i].z,
d = sqrt (dx * dx + dy * dy + dz * dz); /* total distance */
/* compute component and total forces acting on each bead (sum) */
atoms[i].fx += (KEair * atoms[i].chrg *atoms[j].chrg * dx)/(d * d * d);
atoms[i].fy += (KEair * atoms[i].chrg *atoms[j].chrg * dy)/(d * d * d);
atoms[i].fz += (KEair * atoms[i].chrg *atoms[j].chrg * dz)/(d * d * d);
atoms[i].f += (KEair * atoms[i].chrg *atoms[j].chrg)/(d * d);
}
}
for (i = 0; i < NATM; i++) /* output forces on each bead (component and total) */
printf (" atom[%2zu] %5.2f %5.2f %5.2f %+.2f %15.2f %15.2f %5.2f %15.2f\n",
i, atoms[i].x, atoms[i].y, atoms[i].z, atoms[i].chrg,
atoms[i].fx, atoms[i].fy, atoms[i].fz, atoms[i].f);
return 0;
}
/** simple fopen with error check */
FILE *xfopen (const char *fn, const char *mode)
{
FILE *fp = fopen (fn, mode);
if (!fp) {
fprintf (stderr, "xfopen() error: file open failed '%s'.\n", fn);
exit (EXIT_FAILURE);
}
return fp;
}
Example Use/Output
$ ./bin/coulomb
atom[ 0] 1.00 0.00 0.00 +1.00 13844509696.00 -13956823.00 0.00 13831302144.00
atom[ 1] 2.00 0.00 0.00 +1.00 4741866496.00 -13982750.00 0.00 22712082432.00
atom[ 2] 3.00 0.00 0.00 +1.00 2353591552.00 -14002249.00 0.00 24819521536.00
atom[ 3] 4.00 0.00 0.00 +1.00 1171170304.00 -14015272.00 0.00 25635096576.00
atom[ 4] 5.00 0.00 0.00 +1.00 359584800.00 -14021791.00 0.00 25947308032.00
atom[ 5] 6.00 0.00 0.00 +1.00 -359584608.00 -14021791.00 0.00 25947308032.00
atom[ 6] 7.00 0.00 0.00 +1.00 -1171170944.00 -14015272.00 0.00 25635096576.00
atom[ 7] 8.00 0.00 0.00 +1.00 -2353592320.00 -14002249.00 0.00 24819521536.00
atom[ 8] 9.00 0.00 0.00 +1.00 -4741866496.00 -13982751.00 0.00 22712082432.00
atom[ 9] 10.00 0.00 0.00 +1.00 -13844510720.00 -13956824.00 0.00 13831303168.00
atom[10] 1.00 80.00 0.00 -1.00 13844507648.00 13956823.00 0.00 13831302144.00
atom[11] 2.00 80.00 0.00 -1.00 4741867008.00 13982750.00 0.00 22712080384.00
atom[12] 3.00 80.00 0.00 -1.00 2353592064.00 14002249.00 0.00 24819521536.00
atom[13] 4.00 80.00 0.00 -1.00 1171170944.00 14015272.00 0.00 25635096576.00
atom[14] 5.00 80.00 0.00 -1.00 359585056.00 14021791.00 0.00 25947308032.00
atom[15] 6.00 80.00 0.00 -1.00 -359584864.00 14021791.00 0.00 25947308032.00
atom[16] 7.00 80.00 0.00 -1.00 -1171170560.00 14015272.00 0.00 25635096576.00
atom[17] 8.00 80.00 0.00 -1.00 -2353591808.00 14002249.00 0.00 24819521536.00
atom[18] 9.00 80.00 0.00 -1.00 -4741867008.00 13982751.00 0.00 22712080384.00
atom[19] 10.00 80.00 0.00 -1.00 -13844509696.00 13956824.00 0.00 13831304192.00
Looking at the output graphically, the forces increase from the end to a maximum in the center of each string or beads -- that checks, and the forces acting upon the beads in the X-direction is the greatest at each end and reverses direction at midpoint -- also a check. For example:
Total Force Acting on Each Bead
Forces acting in the X direction on Each Bead
Look things over and let me know if you have any questions.
Here's what I would change in your code:
Epsilon and Constant should be declared as constants:
"#define Epsilon0 8.85e-12"
"#define Constant (1/(4*pi*Epsilon0))""
Move the "i != j" inside the loop. That would prevent the loop from stopping if you hit that condition. You would just be skipping that iteration instead of stopping completely.
You don't really need the xi, yi , zij, Fx, Fy, Fz, Rij arrays. You can use simple variables as placeholders instead.
During each iteration of the inner loop, you would be calculating the partial force du to bead j. You need to add that force to the cumulative force.
In order to do that you can declare Fx, Fy and Fz outside of the loops, initialize the 3 variable to 0 inside the first loop and then add partial forces inside the inner loop.
Move the fprintf outside of the inner loop (but keep it inside the external loop)
UPDATE
This code does not handle I/O errors
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define Epsilon0 8.85e-12 // Permittivity of free space (C^2/(N m^2))
#define Constant (1/(4*M_PI*Epsilon0)) // Useful constant
#define ROW 20
int row, col, j;
float x[20], y[20], z[20], q[20], dx, dy, dz, R, Fx, Fy, Fz, F;
int main()
{
FILE *psf=fopen("atom.psf", "r");
FILE *pdb=fopen("beads.pdb", "r");
FILE *fout=fopen("out.txt", "w");
char buffer[1024];
fgets(buffer, 1024, psf);
int i = 0;
for( ; (i<ROW) && (psf != NULL); i++)
{
fscanf (psf,"%*8d%*4s%*4d%*6s%*5s%*6s%11f%*14f%*12d", &q[i]);
fscanf (pdb,"%*4s%*7d%*5s%*4s%*6d%12f%8f%8f%*6f%*6f%*9s", &x[i], &y[i], &z[i]);
}
for(i=0; i<ROW; i++)
{
Fx = Fy = Fz = F = 0.0;
// Loop over other charges to compute force on this charge
for (j=0 ; j<ROW ; j++)
{
//simply skip this itearation
if(i == j)
continue;
// Compute the components of vector distance between two charges
dx = x[i] - x[j];
dy = y[i] - y[j];
dz = z[i] - z[j];
R = sqrt(dx*dx + dy*dy + dz*dz);
// Compute the x and y components of the force between
// these two charges using Coulomb's law
Fx += Constant*q[i]*q[j]*dx/(R*R*R);
Fy += Constant*q[i]*q[j]*dy/(R*R*R);
Fz += Constant*q[i]*q[j]*dz/(R*R*R);
}
F = sqrt(Fx*Fx + Fy*Fy + Fz*Fz);
fprintf(fout, "%d %g %g %g, %g\n", i+1, Fx, Fy, Fz, F);
}
}
Something that may help
The for loop,
`for (j = 0; j<ROW && i != j; j++)`
Will exit when i == j as the loop condition is false. For example when i is 1 will only iterate through the loop once, when j is 0.
Use if statement inside the for loop to skip the current charge, i.e when i == j
for (j = 0; j<ROW ; j++)
{
if (i != j)
{
DO CALCULATION... `
Also, think that Fx[i] will only ever have store the force due to an single j charge as it is assignment for each iteration rather than a sum.
Consider changing to accumlate for each interation, i.e. Fx[i] += then calculate F[i] when this for loop has completed

How to take input from a file using a C program?

I have to take input from a file and convert the number from kelvin to fahrenheit(vice versa), using a "C" program.
Requirements:
The conversion and numeric outputs must take place in the compiled program.
The script will give the user an option to convert either kelvin to fahrenheit or fahrenheit to kelvin.
Numbers need to be rounded to the nearest tenth.
Input file:
0
32
100
212
108
1243
3000
85
22
2388
235
Output File:
Fahrenheit Temperature Kelvin Temperature
0 256
32 273
100 310
212 373
108 315
1243 945
3000 1921
85 302
22 268
2388 1581
235 385
"C" Program:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
//assign the variables used in this program
int temp, conv_temp, conv_type;
//assign the input options to variables
conv_type = atoi(argv[1]);
temp = atoi(argv[2]);
//convert the temps
// if input number is 1, then convert from kelvin to fahrenheit
// if input number is anything else, convert from fahrenheit to kelvin
if(conv_temp == 1)
conv_temp = (((temp - 273) * 1.8) + 32);
else
conv_temp = ((((temp - 32) *5) / 9) + 273);
//print the data
printf(" %3.1i %3.1i\n",temp, conv_temp);
//end of main function
return 0;
}
You have several issues here.
First: you declare "conv_type" and initialize it, but fail to do anything with it.
conv_type;
conv_type = atoi(argv[1]);
Second: before you give a value for "conv_temp" you are attempting to use it in an if statement.
if(conv_temp == 1)
conv_temp = (((temp - 273) * 1.8) + 32);
else
conv_temp = ((((temp - 32) *5) / 9) + 273);
Third: in the problem statement, you state you have to do file I/O.
Here is a link to a tutorial on file IO in C.

stdlib.h rand() % range not from 0 to range

I'm attempting to pick random indexes from a array in C. The problem I'm having is that my random numbers aren't going from the range I expect (from 0 to 2047) as this example says that it will. Just from looking at the indexes I get it seems like I'm getting numbers from 1000-1200 instead of the desired range.
Here's the code which calls rand().
#define MAXPAGES 2048 // maximum number of processes in the system
//until we have a node, pick random indexes.
while(node == NULL){
table_index = rand() % MAXPAGES;
node = table[table_index];
if(node){
fprintf(stderr, "%d\n", table_index);
if(node->current_pages > 0) break;
else node = NULL;
}
}
I call srand only once in my main function.
int main(int argc, char** argv) {
int i;
int simulations = 100000;
// initialize the process hash table
if(argc > 1){
removal_algorithm = atoi(argv[1]);
if(argc == 3) simulations = atoi(argv[2]);
}
srand(time(NULL));
for (i = 0; i < MAXPAGES; i++) table[i] = NULL;
printf("Random replacement MMU simulation on %d simulations started\n", simulations);
Simulate(simulations);
printf("Random MMU simulation completed. only writing page faults:,");
printf("%d, read / write page faults: %d, total page faults: %d\n", read_miss, write_miss, read_miss + write_miss);
}
Example sequence.
1117
1069
1103
1118
1071
1117
1120
1092
1099
1116
1121
1122
1110
1116
1069
1113
1120
1117
1116
1071
1121
1094
1110
1119
1102
1117
1071
1108
1102
1099
1109
1109
1092
1109
1120
1108
1094
1101
1122
1086
1110
1108
1119
1120
1092
1113
1117
1121
Your code obviously prints only those indices, for which table[table_index] is not null. If table[0] is null, it will never print 0. I.e. this code does not necessarily demonstrate the behavior of rand(). Instead it's behavior might be mostly determined by the content of table.

How to print lines from a file in reverse order

I am trying to print a file in reverse order. I am using arrays to save each lines data. So far I was able to print every line in a normal order.
index is the number of lines I am referring to and FuncIndex the same thing but has been declared again in the function.
file = fopen("../quotes.data","r");
while (NumOfField == 8) {
NumOfField = fscanf(file,"%d,%c,%d,%d,%c,%c,%lf,%lf", &quote[index], &roomletter[index], &length[index], &width[index], &paint[index], &ceiling[index], &cost[index], &setup_cost[index]);
index++;
}
index--;
fclose(file);
In Function:
int FuncIndex;
for (FuncIndex = 0; FuncIndex <= index; FuncIndex++) {
printf("\n%5d %1c %3d %3d %1c %1c %8.2lf %6.2lf", quote[FuncIndex], roomletter[FuncIndex], length[FuncIndex], width[FuncIndex], paint[FuncIndex], ceiling[FuncIndex], cost[FuncIndex], setup_cost[FuncIndex]);
}
Now I tried changing the for loop to:
for (FuncIndex = index; FuncIndex >= 0; FuncIndex--) >
But the output prints empty. Although when I change the 0 to any number, that corresponding line gets printed.
The output That prints is:
Quote Room Length Width Paint Ceiling Cost Setup
===== ==== ====== ===== ===== ======= ======= =====
531 A 10 10 b n 96.00 100.00
531 B 15 15 b n 144.00 0.00
531 C 20 20 b n 192.00 0.00
I am looking to get this output reversed like:
Quote Room Length Width Paint Ceiling Cost Setup
===== ==== ====== ===== ===== ======= ======= =====
531 C 20 20 b n 192.00 0.00
531 B 15 15 b n 144.00 0.00
531 A 10 10 b n 96.00 100.00
Please excuse me if I putted the output in the code section because then the formatting would change
Thank you.
Maybe you should post all your code (however, try to reduce it to minimum). This works for me:
File input.txt
530 A
531 B
532 C
#include <stdio.h>
#include <conio.h>
#define MAX_LINES 50
int main()
{
FILE* file;
int NumOfField = 2;
int index = 0;
char roomLetter[ MAX_LINES ];
int quote [ MAX_LINES ];
file = fopen("input.txt","r");
while ( NumOfField == 2 ) {
NumOfField = fscanf(file,"%d %c\n", &quote[index], &roomLetter[index]);
index++;
}
fclose(file);
index--;
for(; index >=0; index-- )
printf( "%d %c\n", quote[index], roomLetter[index] );
getch();
return 0;
}
Ok here is the answer to my question:
the EOF was the trick
for (FuncIndex = index; FuncIndex != EOF; FuncIndex--)
Basically, in here you are saying that whatever the number of index is (Number of Lines) put it in the FuncIndex and then one by one (from the highest number) check each line until its not the end of line anymore.

Resources