Reading a table in a text file using a C program - arrays

Below I have a sample table stored in a text file - random.dat.
0.00 0.01 2.30 300
2.00 0.015 1.45 102
4.00 0.03 6.08 174
6.00 5.95 0.05 225
Now I want to read the contents of the table and store into an array. I have the following code that almost does the job.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
int i,j;
int M = 3, N = 3;
FILE *fp;
double value1[M][N];
fp = fopen("random.dat","r");
if (fp == NULL)
{
exit(1);
}
for (i = 0; i < M; i++)
{
for (j = 0; j < N; j++)
{
fscanf(fp, "%lf", &value1[i][j]);
if (feof(fp))
{
break;
}
}
}
\*Just to check that my code has stored the arrays properly, I put the following printf statements*/
printf("%lf\n", value1[0][0]);
printf("%lf\n", value1[0][1]);
printf("%lf\n", value1[0][2]);
printf("%lf\n", value1[0][3]);
printf("%lf\n", value1[1][0]);
printf("%lf\n", value1[1][1]);
printf("%lf\n", value1[1][2]);
printf("%lf\n", value1[1][3]);
}
The values that I want and thought the program would give me:
value1[0][0] = 0.00 value1[0][1] = 0.01 value1[0][2] = 2.30 value1[0][3] = 300
value1[1][0] = 2.00 value1[1][1] = 0.015 value1[1][2] = 1.45 value1[1][3] = 102
Instead, it gives me,
value1[0][0] = 0.00 value1[0][1] = 0.01 value1[0][2] = 2.30 value1[0][3] = 300.0
value1[1][0] = 300.0 value1[1][1] = 2.00 value1[1][2] = 0.015 value1[1][3] = 1.45
I couldn't figure out a solution for this. Can someone point where I have made an error?
Thank you

If M and N are 3, value1 [0] [3] is out of bounds. Change N to 4.

Related

Can't read integers from File one by one correctly

In my case I can print the 50 4digits random generated numbers into the file named rastgele.txt but then ı need to read them from file one by one and store them in the array named dosyaOkuma[] and print them to the screen. But when ım try to scan and print them ı get irrelevant numbers so ı cant read them correctly from file. I need some help about reading int numbers from file correctly.
Here is my File format:
2862 3232 2869 2993 1303 3799 2257 2296 2105 3502 1318 3348 1851 3741 1468 1605 1994 1005 2211 1646 3056 3319 2273 1436 2621 1882 3856 2869 2026 2789 2055 1205 1263 1051 3059 3275 2876 1703 3674 1539 2381 2513 2415 3613 1066 3796 2710 2578 1294 3255
Here is my code:
#include <stdlib.h>
int main(){
FILE *file;
int sayilar[50];
int dosyaOkuma[50];
int i,x,y;
srand ( time(NULL) );
for (i = 0; i < 50; i++) {
int num = (rand() % 2999) +1000;
sayilar[i] = num;
}
file = fopen("rastgele.txt","w");
for(x=0;x<50;x++){
fprintf(file,"%d ",sayilar[x]);
}
printf("Olusuturulan rastgele sayilar rastgele.txt dosyasina yazdirildi...");
for(y=0;y<50;y++){
fscanf(file,"%d",&dosyaOkuma[y]); //where ı read file...
printf("\n%d. sayi = %1d",y+1,dosyaOkuma[y]); //where ı print files to screen...
}
return 0;
}
And here is my program output:
1. sayi = 101
2. sayi = 0
3. sayi = -285212433
4. sayi = 32765
5. sayi = 0
6. sayi = 0
7. sayi = 0
8. sayi = 0
9. sayi = 0
10. sayi = 0
11. sayi = -1697181492
...
Include stdio.h and time.h
Add rewind after writing and before reading.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main ( void){
FILE *file = NULL;
int sayilar[50] = { 0};
int dosyaOkuma[50] = { 0};
int i = 0, x = 0, y= 0;
srand ( time(NULL) );
for (i = 0; i < 50; i++) {
int num = (rand() % 2999) +1000;
sayilar[i] = num;
}
if ( NULL != ( file = fopen("rastgele.txt","w+"))) {
for ( x = 0; x < 50; x++) {
fprintf ( file,"%d ",sayilar[x]);
}
printf ( "Olusuturulan rastgele sayilar rastgele.txt dosyasina yazdirildi...");
rewind ( file);
for ( y = 0; y < 50; y++) {
if ( 1 == fscanf(file,"%d",&dosyaOkuma[y])) {
printf("\n%d. sayi = %1d",y+1,dosyaOkuma[y]);
}
}
fclose ( file);
}
return 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

C Program: Why does this array have this output?

Ok so I have never taken a C programming course and I have a general idea of what Arrays are, but I cant seem to figure out why this array has a certain output.
#include <stdio.h>
#include <time.h>
#include <stdlib.h> // include srand function
#pragma warning(disable : 4996)
#define Size 15
main() {
int a[Size];
int i;
double b1[Size], b2[Size];
srand( (unsigned)time( NULL ) ); // Use current time as seed
// apply (start) timestamp
for (i = 0; i < Size; i++)
{
a[i] = rand() % 100;
// initialize the array using random number between 0 and 99
b1[i] = a[i]/5;
printf("a[%d] = %d\n", i, a[i]);
printf("b1[%d] = %f\n", i, b1[i]);
b2[i] = a[i];
b2[i] = b2[i]/5;
printf("b2[%d] = %f\n", i, b2[i]);
}
// apply (end) timestamp
//compute the time elapsed and display time in seconds
}
For my homework I need to run this code and explain why b1 and b2 have same or different values. I cant seem to wrap my head around what is happening here:
for (i = 0; i < Size; i++)
{
a[i] = rand() % 100;
// initialize the array using random number between 0 and 99
b1[i] = a[i]/5;
printf("a[%d] = %d\n", i, a[i]);
printf("b1[%d] = %f\n", i, b1[i]);
b2[i] = a[i];
b2[i] = b2[i]/5;
printf("b2[%d] = %f\n", i, b2[i]);
}
If someone could explain what the code is doing here I would very much appreciate it.
Thanks!
Edit- This is the output once I run the program:
a[0] = 8
b1[0] = 1.000000
b2[0] = 1.600000
a[1] = 74
b1[1] = 14.000000
b2[1] = 14.800000
a[2] = 78
b1[2] = 15.000000
b2[2] = 15.600000
a[3] = 64
b1[3] = 12.000000
b2[3] = 12.800000
a[4] = 53
b1[4] = 10.000000
b2[4] = 10.600000
a[5] = 6
b1[5] = 1.000000
b2[5] = 1.200000
a[6] = 71
b1[6] = 14.000000
b2[6] = 14.200000
a[7] = 4
b1[7] = 0.000000
b2[7] = 0.800000
a[8] = 7
b1[8] = 1.000000
b2[8] = 1.400000
a[9] = 57
b1[9] = 11.000000
b2[9] = 11.400000
a[10] = 55
b1[10] = 11.000000
b2[10] = 11.000000
a[11] = 13
b1[11] = 2.000000
b2[11] = 2.600000
a[12] = 55
b1[12] = 11.000000
b2[12] = 11.000000
a[13] = 96
b1[13] = 19.000000
b2[13] = 19.200000
a[14] = 25
b1[14] = 5.000000
b2[14] = 5.000000
Because you implicitly convert int to double and both times do that different ways.
b1[i] = a[i] / 5 ;
/* ^ ^ int ^
* | +-- int
* +-- implicit convertion to double */
b2[i] = b2[i] / 5 ;
/* ^ double ^
* + int implicitly converted
* to double */
In first expression you divide int by int where you lose precision (i.e. 7 / 2 gives you 3, not 3.5),
In second expression you divide double by double. That doesn't lead to that.

Convert a matrix A in a sparse formats CSR, COO, etc

I have a little problem, I would like to convert a matrix 10*10 in a CSR or COO sparse matrix/format. The matrix is:
1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
-0.45 0.10 -0.45 0.00 0.00 0.00 0.00 0.00 0.00 0.00
0.00 -0.45 0.10 -0.45 0.00 0.00 0.00 0.00 0.00 0.00
0.00 0.00 -0.45 0.10 -0.45 0.00 0.00 0.00 0.00 0.00
0.00 0.00 0.00 -0.45 0.10 -0.45 0.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00 -0.45 0.10 -0.45 0.00 0.00 0.00
0.00 0.00 0.00 0.00 0.00 -0.45 0.10 -0.45 0.00 0.00
0.00 0.00 0.00 0.00 0.00 0.00 -0.45 0.10 -0.45 0.00
0.00 0.00 0.00 0.00 0.00 0.00 0.00 -0.45 0.10 -0.45
0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00
I am using the "CUSP" functions but it did not work, once tha matrix A I would like just to convert in other format. Can you help me?
Well I would like also to use this matrix to solve the system Ax=b, using bicgstab:
b=
0.00000
0.34202
0.64279
0.86603
0.98481
0.98481
0.86603
0.64279
0.34202
0.00000
My code for this is:
int n = 10, r;
cusp::coo_matrix<int,float,cusp::device_memory> A(n, n, 3*n - 4);
cusp::array1d<float, cusp::device_memory> x(A.num_rows, 0);
cusp::array1d<float, cusp::device_memory> b(A.num_rows, 1);
b[0]=0.00000;
b[1]=0.34202;
b[2]=0.64279;
b[3]=0.86603;
b[4]=0.98481;
b[5]=0.98481;
b[6]=0.86603;
b[7]=0.64279;
b[8]=0.34202;
b[9]=0.00000;
i=0;
// row 0
A.row_indices[i] = 0.0;
A.column_indices[i] = 0.0;
A.values[i] = 1.00;
++i;
// rows 1 through n - 2
for (r = 1; r != n - 1; ++r) {
A.row_indices[i] = r;
A.column_indices[i] = r - 1;
A.values[i] = -0.45;
++i;
A.row_indices[i] = r;
A.column_indices[i] = r;
A.values[i] = 0.10;
++i;
A.row_indices[i] = r;
A.column_indices[i] = r + 1;
A.values[i] = -0.45;
++i;
}
// row n - 1
A.row_indices[i] = n - 1;
A.column_indices[i] = n - 1;
A.values[i] = 1.00;
++i;
// set stopping criteria:
// iteration_limit = 100
// relative_tolerance = 1e-3
cusp::verbose_monitor<ValueType> monitor(b, 100, 1e-3);
// set preconditioner (identity)
cusp::identity_operator<ValueType, MemorySpace> M(A.num_rows, A.num_rows);
// solve the linear system A x = b
cusp::krylov::bicgstab(A, x, b, monitor, M);
cusp::print(x);
The result using Octave should be something similar to:
0.00000
0.32441
0.60970
0.82144
0.93411
0.93411
0.82144
0.60970
0.32441
0.00000
But is also with negative numbers, so WRONG.
For COO, you have to set three array elements for each entry: the row and column indices as well as the value. You can create a matrix like the one you describe using code like this for COO:
int n = 10, i = 0, r;
cusp::csr_matrix<int,float,cusp::host_memory> A(n, n, 3*n - 4);
// row 0
A.row_indices[i] = 0;
A.column_indices[i] = 0;
A.values[i] = 1.00;
++i;
// rows 1 through n - 2
for (r = 1; r != n - 1; ++r) {
A.row_indices[i] = r;
A.column_indices[i] = r - 1;
A.values[i] = -0.45;
++i;
A.row_indices[i] = r;
A.column_indices[i] = r;
A.values[i] = 0.10;
++i;
A.row_indices[i] = r;
A.column_indices[i] = r + 1;
A.values[i] = -0.45;
++i;
}
// row n - 1
A.row_indices[i] = n - 1;
A.column_indices[i] = n - 1;
A.values[i] = 1.00;
++i;
For CSR you have to specify a column and a value for every entry, and also the index of the first entry for every row including a one-past-the-end index for the one-past-the-end row. A similar piece of code for CSR:
int n = 10, i = 0, r = 0;
cusp::csr_matrix<int,float,cusp::host_memory> A(n, n, 3*n - 4);
// row 0
A.row_offsets[r] = i;
A.column_indices[i] = 0;
A.values[i] = 1.00;
++i;
// rows 1 through n - 2
for (++r; r != n - 1; ++r) {
A.row_offsets[r] = i;
A.column_indices[i] = r - 1;
A.values[i] = -0.45;
++i;
A.column_indices[i] = r;
A.values[i] = 0.10;
++i;
A.column_indices[i] = r + 1;
A.values[i] = -0.45;
++i;
}
// row n - 1
A.row_offsets[r] = i;
A.column_indices[i] = r;
A.values[i] = 1.00;
++i;
++r;
A.row_offsets[r] = i;
To “convert” the matrix from some other format, you have to let us know in what form your original data is stored. Conversion from a cusp::array2d should work by simply passing that array to the constructor. In general, creating the matrix in sparse format in the first place like the code above does will provide better scalability.
Also note that your example matrix is arranged in diagonal bands, so cusp::dia_matrix would be better suited, both in terms of easy encoding and in terms of better performance. To create such a tridiagonal matrix, you can use the following code:
int n = 10, r = 0;
cusp::dia_matrix<int,float,cusp::host_memory> A(n, n, 3*n - 4, 3);
A.diagonal_offsets[0] = -1;
A.diagonal_offsets[1] = 0;
A.diagonal_offsets[2] = 1;
// row 0
A.values(r,0) = A.values(r,2) = 0.00;
A.values(r,1) = 1.00;
// rows 1 through n - 2
for (++r; r != n - 1; ++r) {
A.values(r,0) = A.values(r,2) = -0.45;
A.values(r,1) = 0.10;
}
// row n - 1
A.values(r,0) = A.values(r,2) = 0.00;
A.values(r,1) = 1.00;
About this linear equation you try to solve: could it be that octave is operating on a different matrix than the one you pasted into your question? Because with sage I get negative numbers in the result as well:
n = 10
d = dict()
d[(0,0)] = d[(n-1, n-1)] = 1
for r in range(1, n-1):
d[(r, r-1)] = d[(r, r+1)] = -45/100
d[(r,r)] = 1/10
A = matrix(RDF, n, n, d)
b = vector(RDF, [
0.00000,
0.34202,
0.64279,
0.86603,
0.98481,
0.98481,
0.86603,
0.64279,
0.34202,
0.00000,
])
for i in A.solve_right(b):
print('{:+.5f}'.format(float(i)))
gives the following vector x:
+0.00000
-0.45865
-0.86197
-1.16132
-1.32062
-1.32062
-1.16132
-0.86197
-0.45865
+0.00000

read in doubles from a text file (using C / Visual Studio)

I have a text file with numbers: two numbers on each row, separated by a space. Each pair of numbers represents an (x, y) co-ordinate. I am trying to write this in C, because it's the language I know, but I am working in Visual Studio 2010. The code I have is as follows:
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#define MAXPOINTS 10
int _tmain(int argc, _TCHAR* argv[])
{
double points [MAXPOINTS];
int i;
for (i = 0; i < MAXPOINTS; i++) {
points[i] = 0.0;
}
FILE* pFile;
pFile = fopen ("points.txt","r");
if (pFile == NULL)
{
printf("Could not open file\n");
return 0;
}
rewind (pFile);
i = 0;
while (fscanf(pFile, "%f %f", &points[i], &points[i + 1]) == 2) {
printf("blah\n");
i = i + 2;
}
for (i = 0; i < MAXPOINTS; i++) {
printf("[%d] = %f\n", i, points[i]);
}
fclose (pFile);
return 0;
}
The output is:
blah
blah
blah
[0] = 0.000000
[1] = 0.000000
[2] = 0.000000
[3] = 0.000000
[4] = 0.000000
[5] = 0.000000
[6] = 0.000000
[7] = 0.000000
[8] = 0.000000
[9] = 0.000000
Where points.txt has three rows:
100 200
300 400
500 500
I can't figure out why the numbers aren't being read into the array.
Any ideas?
%f format requires pointer to float, and you give pointer to double.

Resources