Array sums with MPI_Gather and MPI_Scatter - c

I'm completely new with MPI, and I have to solve a problem: I have 2 1D arrays (A and B), which I have to sum the contents of, and store the result in a different array (C). I've done an example using just one array, in which I sum all the contents of, then returning the result.
How can I adapt this with Gather and Scatter?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"mpi.h"
#define N 10
int* CreaArreglo(tam){
int* arr;
arr = (int*)malloc(tam*sizeof(int));
return arr;
}
int* GeneraArreglo(int tam){
int* arr;
arr = (int*)malloc(tam*sizeof(int));
int i;
srand(time(0));
for(i = 0; i < tam ; i++)
{
arr[i]=rand()%40;
}
return arr;
}
int main(int argc,char*argv[])
{
MPI_Status status;
int idProc , numProc;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&idProc);
MPI_Comm_size(MPI_COMM_WORLD,&numProc);
int nDatos = N/(numProc-1);
int nDatosU = nDatos + (N%(numProc-1));
if(idProc == 0){
int* A;
A = GeneraArreglo(N);
int i;
for(i=1;i <= numProc-2;i++){
MPI_Send(A+((i-1)*nDatos),nDatos,MPI_INT,i,0,MPI_COMM_WORLD);
}
MPI_Send(A+((i-1)*nDatos),nDatosU,MPI_INT,i,0,MPI_COMM_WORLD);
int suma = 0;
int sumap = 0;
i = 1;
do{
MPI_Recv(&sumap,1,MPI_INT,i,0,MPI_COMM_WORLD,&status);
suma += sumap;
i++;
}while(i<(numProc));
printf("suma total = %d \n",suma);
}
else{
if(idProc == numProc-1){
nDatos = nDatosU;
}
int suma = 0;
int i=0 ;
int* A = CreaArreglo(nDatos);
MPI_Recv(A,nDatos,MPI_INT,0,0,MPI_COMM_WORLD,&status);
i=0;
do{
printf("%d +",A[i]);
suma += A[i];
i++;
}while(i<(nDatos));
MPI_Send(&suma,1,MPI_INT,0,0,MPI_COMM_WORLD);
}
MPI_Finalize();
}

Related

Print elements from an array member of a structure in C

I have been solving a problem of CyclicRotation. This is my code:
#include<stdio.h>
#include<stdlib.h>
struct Results{
int *A;
int N;
};
struct Results solution(int A[], int N, int K){
struct Results result;
int *tab, i=0, j=0;
tab = (int*) malloc(N*sizeof(int));
if(N==0){
result.A = A;
result.N = N;
return result;
}
if(K>N){
K = K % N;
}
if(K<N && N != 0){
for(i=N-K;i<N;i++){
tab[j] = A[i];
j = j + 1;
}
i = 0;
while(i<N-K){
tab[j] = A[i];
i++;
j++;
}
} else {
tab = A;
}
result.A = tab;
result.N = N;
return result;
}
int main()
{
int j[]={2,3,4,5,6,7,8};
int mylen;
int myk = 3;
mylen = sizeof(j)/sizeof(j[0]);
return 0;
}
I tried this in the code:
int main()
{
int j[]={2,3,4,5,6,7,8};
int mylen;
int myk = 3;
mylen = sizeof(j)/sizeof(j[0]);
printf("The result is %d",solution(j,mylen,myk).A);
return 0;
}
The expected result is 6782345, but the result in the console is different:
The result is -591373584
I'm not sure if the array printing is correct (given that is an array, perhaps I need a loop?). Please, could you give me a help? Thank you in advance.
int main()
{
int j[]={2,3,4,5,6,7,8};
int mylen;
int myk = 3;
mylen = sizeof(j)/sizeof(j[0]);
struct Results results = solution(j, mylen, myk);
for(int i = 0; i < mylen; i++)
printf("%d\n", results.A[i]);
free(results.A);
return 0;
}

Why does my addArrays function get a wedge exit compile code? (UPDATE FIXED)

The rest of my functions work fabulously, however the last function has my goat. The goal of this function is to use pointers to obtain the values of two different arrays and add those values to a third array. However, when I run the main method to make the function run, it pauses for a second and provides a wedge exit code that does not work.
I've tried removing the if((sizeof(*ptr1)) == (sizeof(*ptr2)){
---insert code here---
}
from the for loop, however, the problem seems to be just the for loop itself.
//===================================Broken Code========================================
#include <stdio.h>
#define MAXIMUM 1000
int sumArrays(int arr1[], int arr2[]);
int addArrays(int arr1[], int arr2[]);
int main()
{
int arrayOne[MAXIMUM];
int arrayTwo[MAXIMUM];
for(int i = 0; i <= MAXIMUM; i++)
arrayOne[i] = i;
printf("Arrayone %d\n", arrayOne);
for(int j = 0; j <= MAXIMUM; j++)
arrayTwo[j] = j;
printf("ArrayTwo %d\n", arrayTwo);
printf(" The sum of the arrays is : %d\n",sumArrays(arrayOne, arrayTwo));
printf("%d", addArrays(arrayOne, arrayTwo));
return 0;
}
int sumArrays(int arr1[],int arr2[]){
int *ptr_1;
int *ptr_2;
ptr_1 = &arr1[0];
ptr_2 = &arr2[0];
int sum;
for(int i = 0; i < MAXIMUM; i++){
sum += *ptr_1 + i;
sum += *ptr_2 + i;
}
return sum;
}
int addArrays(int arr1[],int arr2[]){
int *ptr1 = &arr1[0];
int *ptr2 = &arr2[0];
int sum = 0;
int i = 0;
int arr3[0];
if(sizeof(*ptr1) == sizeof(*ptr2)){
for(int i = 0; i < MAXIMUM; i++){
sum += *ptr1 +i;
sum += *ptr2 +i;
arr3[i] = sum;
}
}
printf("The value of array3 is %d", arr3);
}
The other function works perfectly, but the addArrays function does a wedge exit and doesn't cooperate.
I expect the addArrays function to take the elements from each array, add them together and assign them to the third array.
Thank you for your time.
UPDATE: WORKING CODE
#include <stdio.h>
#define MAXIMUM 1000
#define ARRAY_SZ(x) (sizeof(x) / sizeof((x)[0]))
int sumArrays(int arr1[], int arr2[], size_t len);
int addArrays(int arr1[], int arr2[], int arr3[], size_t len);
int main()
{
int arrayOne[MAXIMUM];
int arrayTwo[MAXIMUM];
int arrayThree[MAXIMUM];
for(int i = 0; i <= MAXIMUM; i++)
arrayOne[i] = i;
printf("Array One %d\n", ARRAY_SZ(arrayOne));
for(int j = 0; j <= MAXIMUM; j++)
arrayTwo[j] = j;
printf("Array Two %d\n", ARRAY_SZ(arrayTwo));
printf(" The sum of the arrays is : %d\n",sumArrays(arrayOne, arrayTwo, ARRAY_SZ(arrayOne)));
printf("%d", addArrays(arrayOne, arrayTwo, arrayThree, MAXIMUM));
return 0;
}
int sumArrays(int arr1[],int arr2[], size_t len){
int *ptr_1;
int *ptr_2;
ptr_1 = &arr1[0];
ptr_2 = &arr2[0];
int sum = 0 ;
for(int i = 0; i < len; i++){
sum += *ptr_1++;
sum += *ptr_2++;
}
return sum;
}
int addArrays(int arr1[],int arr2[], int result[], size_t len){
int *ptr1 = &arr1[0];
int *ptr2 = &arr2[0];
int *ptr3 = &result[0];
int sum = 0;
int sum2 = 0;
int i = 0;
for(int i = 0; i < MAXIMUM; i++){
sum = *ptr1 ++;
sum += *ptr2 ++;
result[i] = sum;
printf("The result of array 3 is %d\n", *ptr3++);
}
}
Here are some notes:
When you assign/pass/print the and array using the name of the array, you are actually passing the memory location of the first element in the array (a pointer).So when you write:
printf("Arrayone %d\n", arrayOne);
You will see the memory address of the first element of the array being printed. If you would like to print the entire array you will need to loop through it. In this case you would be printing 1000 integers which might be undesirable.
void printArray(int * array, size_t len)
{
while(len--)
{
printf("%d ", *array++);
}
}
To get the number of elements in an array you can do something like this:
sizeof(arrayOne) / sizeof(arrayOne[0])
and you can put it in a macro like this:
#define ARRAY_SZ(x) (sizeof(x) / sizeof((x)[0]))
and call it like this:
ARRAY_SZ(arrayOne);
You cannot get the array size if you are receiving an array in a function (it has decayed to a pointer), instead you should pass the array size to the function too. Here because you initialize the arrays with the size MAXIMUM we don't actually need to calculate the array size, but we can just to show it works.
If you want to return an array (like in addArrays()) you should create an empty array and pass it to the function, then the function can update the array with the result.
When looping through an array you never want to do array[maximum] because the array indices range from 0 to maximum - 1
#include <stdio.h>
#define MAXIMUM 1000
#define ARRAY_SZ(x) (sizeof(x) / sizeof((x)[0]))
int sumArrays(int arr1[], int arr2[]);
int addArrays(int arr1[], int arr2[]);
int main()
{
int arrayOne[MAXIMUM];
int arrayTwo[MAXIMUM];
int arrayThree[MAXIMUM];
for(int i = 0; i < MAXIMUM; i++)
arrayOne[i] = i;
printf("Array one size %d\n", ARRAY_SZ(arrayOne));
for(int j = 0; j < MAXIMUM; j++)
arrayTwo[j] = j;
printf("Array Two size %d\n", ARRAY_SZ(arrayTwo));
printf(" The sum of the arrays is : %d\n",sumArrays(arrayOne, arrayTwo, ARRAY_SZ(arrayOne)));
addArrays(arrayOne, arrayTwo, arrayThree, MAXIMUM);
return 0;
}
int sumArrays(int arr1[],int arr2[], size_t len)
{
int *ptr_1;
int *ptr_2;
ptr_1 = &arr1[0];
ptr_2 = &arr2[0];
int sum;
for(int i = 0; i < len; i++){
sum += *ptr_1 + i;
sum += *ptr_2 + i;
}
return sum;
}
void addArrays(int arr1[], int arr2[], int result[], size_t len){
int *ptr1 = arr1;
int *ptr2 = arr2;
int sum = 0;
int i = 0;
for(int i = 0; i < len; i++){
sum = *ptr1 +i;
sum += *ptr2 +i;
result[i] = sum;
}
}

C program works fine while debugging but the execution fails for some inputs

This is a sample implementation of KD-tree.
Where I first take number of dimensions, number of points, number of clusters to be formed. Bi-partition function calculates centroid, dimension which has max variance. Now based on the max dimensions mean I start splitting the points. This program works fine when input is (dimensions-2,points-20,clusters-4). But does not work for (dimensions-2,points-20,clusters-8). When I debug the program it gives proper output.But when I run the program it stops working.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <stdbool.h>
int *gendata(int num);
void bipartition_fn(int dimensions,int nodes,int i0, int im, int *data,int *cluster_size,int *cluster_start, int *cluster_bdry, int *cluster_centroid);
void kdtree_fn(int dimensions, int nodes, int k, int *data,int *k_cluster_size,int **k_cluster_centroid,int *k_cluster_start,int **k_cluster_bdry );
int main()
{
int dimensions,nodes,i,k,j;
printf("enter the number of dimensions");
scanf("%d",&dimensions);
printf("enter the total number of elements in multiples of dimensions");
scanf("%d", &nodes);
printf("enter number of clusters");
scanf("%d",&k);
int *data;
int *k_cluster_size;
int **k_cluster_centroid;
int *k_cluster_start;
int **k_cluster_bdry;
data = gendata(nodes); /*dynamic array generation for data points*/
k_cluster_bdry=(int **)malloc(k*sizeof(int *));
for(i=0;i<(2*k-2);i++)
*(k_cluster_bdry+i)=(int *)malloc(2*dimensions*sizeof(int));
k_cluster_centroid=(int **)malloc(k*sizeof(int *));
for(i=0;i<(2*k-2);i++)
*(k_cluster_centroid+i)=(int *)malloc(dimensions*sizeof(int));
k_cluster_size=malloc((2*k-2)*sizeof(int));
k_cluster_start = malloc((2*k-2)*sizeof(int));
/*calling the kdtree function*/
kdtree_fn(dimensions, nodes, k, data, k_cluster_size, k_cluster_centroid, k_cluster_start, k_cluster_bdry);
/*printing the cluster size */
printf("cluster size \n");
for(i=k-2; i<(2*k - 2); i++){
printf("%d ", k_cluster_size[i]);
}
free(data);
free(k_cluster_bdry);
free(k_cluster_centroid);
free(k_cluster_size);
free(k_cluster_start);
return 0;
}
void kdtree_fn(int dimensions, int nodes, int k, int *data,int *k_cluster_size,int **k_cluster_centroid,int *k_cluster_start,int **k_cluster_bdry){
int i,j,d0,dm,x,m=0,l,n=0,check=1,s,temp=0;
d0 = 0, dm =nodes ;
int *cluster_size, *cluster_start;
int *cluster_bdry;
int *cluster_centroid;
int *query;
int *res;
query = (int *)malloc(sizeof(int)*dimensions);
res = (int *)malloc(sizeof(int)*dimensions);
cluster_centroid = (int*)malloc(dimensions*sizeof(int));
cluster_bdry = (int*)malloc(4*dimensions*sizeof(int));
cluster_size=(int*)malloc(2*sizeof(int));
cluster_start = (int*)malloc(2*sizeof(int));
/* iterating k-1 times to form k clusters */
for(x=0 ; x<k-1; x++){
bipartition_fn(dimensions, nodes, d0, dm, data, cluster_size, cluster_start, cluster_bdry, cluster_centroid);
for( i=0;i<dimensions; i++){
k_cluster_centroid[x][i] = cluster_centroid[i];
}
for( i=0;i<2; i++){
k_cluster_size[m] = cluster_size[i];
k_cluster_start[m] = cluster_start[i];
m++;
}
int p=0,r=0;
while(p<2){
l=0;
i=0;
while(i<2*dimensions){
k_cluster_bdry[temp][l] = cluster_bdry[r];
l++;
i++;
r++;
}
temp++;
p++;
}
s = pow(2,check);
if(x == 0 ||(x%(s-2)) == 0){
d0 =0;
nodes = k_cluster_size[n];
check++;
n++;
}
else{
d0 = d0+k_cluster_size[n-1];
nodes = k_cluster_size[n];
n++;
}
}
free(cluster_bdry);
free(cluster_centroid);
free(cluster_size);
free(cluster_start);
}
/*Each bipartition function gives 2 clusters*/
void bipartition_fn(int dimensions,int nodes,int d0, int dm, int *data,int *cluster_size,int *cluster_start, int *cluster_bdry, int *cluster_centroid){
int i,j,x,k;
int node = nodes/dimensions;
int sum,min,max;
int *cluster_assign;
cluster_assign = malloc(nodes*sizeof(int));
int *assign;
assign= (int *)malloc(node*sizeof(int));
// printf("nodes: %d \n", nodes);
/*calculate centroid and boundaries*/
i=0;
j=d0;
while(i<dimensions){
sum=0;
while(j<(d0+nodes)){
sum = sum+data[j];
j = j+dimensions;
}
cluster_centroid[i] = sum/node;
i = i+1;
j=d0+i;
}
/* Calculate variance of each dimension and find dimension with maximum variance*/
int var[dimensions],g,h;
h=d0;
g=0;
while(g<dimensions){
sum = 0;
while(h<(d0+nodes)){
sum = sum +((cluster_centroid[g] - data[h])*(cluster_centroid[g] - data[h]));
h=h+dimensions;
}
var[g] = sum/node;
g=g+1;
h=(d0+g);
}
int large = var[0];
int max_dimension =0;
int p;
for(p=0; p<dimensions; p++){
if(var[p]>large){
large = var[p];
max_dimension = p;
}
}
/* find mean of maximum variance*/
int mean = cluster_centroid[max_dimension];
//printf("mean %d \n",mean);
i=d0+max_dimension;
x=0;
while(i<(d0+nodes)){
if(data[i] < mean){
assign[x]=0;
}
else{
assign[x]=1;
}
x++;
i= i+dimensions;
}
/* Rearranging the points based on mean points lesser than mean goes to left and greater than mean goes to right*/
x=0;
int count=0;
int y=0;
for(i=0; i<node; i++){
if(assign[y] == 0){
count++;
for(j=dimensions*i; j<dimensions*(i+1); j++){
cluster_assign[x] = data[d0+j];
x++;
}
}
y++;
}
cluster_size[0] = count*dimensions;
cluster_start[0]= d0;
count=0;
y=0;
for(i=0; i<node; i++){
if(assign[y]!=0){
count++;
for(j=dimensions*i; j<dimensions*(i+1); j++){
cluster_assign[x] = data[d0+j];
x++;
}
}
y++;
}
cluster_size[1] = count*dimensions;
cluster_start[1]= d0+cluster_size[0];
int temp1,temp2;
x=0;
p=0;
while(p<2){
j=cluster_start[p];
i=0;
while(i<dimensions){
min=data[j];
max=data[j];
temp1=cluster_start[p];
temp2=cluster_size[p];
while(j < temp1+temp2){
if(data[j]<min)
min = data[j];
if(data[j]>max)
max= data[j];
j = j+dimensions;
}
cluster_bdry[x]=min;
x=x+1;
cluster_bdry[x]=max;
x=x+1;
i = i+1;
j=temp1+i;
}
p++;
}
/*printf("bou");
for(i=0; i<4*dimensions; i++){
printf("%d ",cluster_bdry[i]);
} */
free(cluster_assign);
free(assign);
}
/*Initialize data array*/
int *gendata(int num)
{
int *ptr = (int *)malloc(sizeof(int)*num);
int j = 0;
if(ptr != NULL)
{
for(j = 0; j < num; j++)
{
ptr[j] = -50 + rand()%101;
}
}
return ptr;
}

Why are my median and mean not returning anything?

The following code is trying to find the averages of a set of numbers in C, but the median and the mean both do not return anything. How do I make it so the mean and the median both return a float? Am I returning an invalid value or?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int compare (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
float mean(int arr[], int size){
int sum = 0;
for(int i = 0; i<size; i++){
sum += arr[i];
}
return ((float)sum/size);
}
int range(int arr[], int size){
int smallest = arr[0];
int largest = arr[0];
for(int i=0; i<size; i++){
if(smallest>arr[i]){
smallest = arr[i];
} if(largest<arr[i]){
largest = arr[i];
}
} int difference = largest - smallest;
return difference;
}
int mode(int arr[], int size){
int maxValue = 0;
int maxCount = 0;
for(int i = 0; i<size; i++){
int count = 0;
for(int j = 0; j<size; j++){
if(arr[j] == arr[i]){
count++;
}
} if(count > maxCount){
maxCount = count;
maxValue = arr[i];
}
} return maxValue;
}
float median(int arr[], int size){
qsort(arr, size, sizeof(int), compare);
float middleOfArray = size/2;
int roundedMiddleOfArray = rint(middleOfArray);
if(ceilf(middleOfArray) == middleOfArray){
return((float)arr[roundedMiddleOfArray]);
}
else{
return((float)arr[roundedMiddleOfArray] - arr[roundedMiddleOfArray-1]);
}
}
int main(){
int array[6] = {1,2,3,4,5,6};
int newMean = mean(array, 5);
int newRange = range(array, 5);
int newMode = mode(array,5);
int newMedian = median(array, 5);
printf("The mean is : %f \n", newMean);
printf("The range is : %d \n",newRange);
printf("The mode is : %d \n",newMode);
printf("The median is : %f \n", newMedian);
return 0;
}
Turns out the way you fix it is by declaring the mean and the median as floats not ints (in main).

crash on trying to reallocate a pointer using pointer to this pointer

I have a pointer to a pointer ("paths") and I want to reallocate each pointer (each "path"). But I get a crash. Generally I am trying to find all possible powers of a number, which one can compute for some amount of operations (e.g for two operations we can get power of three and four (one operation for square of a number, then another one either for power of three or four)). I figured out how to do it on paper, now I am trying to implement it in code. Here is my try:
#include <stdio.h>
#include <stdlib.h>
void print_path(const int *path, int path_length);
int main(void)
{
fputs("Enter number of operations? ", stdout);
int operations;
scanf("%i", &operations);
int **paths, *path, npaths, npath;
npaths = npath = 2;
path = (int*)malloc(npath * sizeof(int));
paths = (int**)malloc(npaths * sizeof(path));
int i;
for (i = 0; i < npaths; ++i) // paths initialization
{
int j;
for (j = 0; j < npath; ++j)
paths[i][j] = j+1;
}
for (i = 0; i < npaths; ++i) // prints the paths, all of them are displayed correctly
print_path(paths[i], npath);
for (i = 1; i < operations; ++i)
{
int j;
for (j = 0; j < npaths; ++j) // here I am trying to do it
{
puts("trying to reallocate");
int *ptemp = (int*)realloc(paths[j], (npath + 1) * sizeof(int));
puts("reallocated"); // tried to write paths[j] = (int*)realloc...
paths[j] = ptemp; // then tried to make it with temp pointer
}
puts("memory reallocated");
++npath;
npaths *= npath; // not sure about the end of the loop
paths = (int**)realloc(paths, npaths * sizeof(path));
for (j = 0; j < npaths; ++j)
paths[j][npath-1] = paths[j][npath-2] + paths[j][j];
for (j = 0; j < npaths; ++j)
print_path(paths[j], npath);
puts("\n");
}
int c;
puts("Enter e to continue");
while ((c = getchar()) != 'e');
return 0;
}
void print_path(const int *p, int pl)
{
int i;
for (i = 0; i < pl; ++i)
printf(" A^%i -> ", p[i]);
puts(" over");
}
I am not sure the problem resides with the call to realloc(), rather you are attempting to write to locations for which you have not created space...
Although you create memory for the pointers, no space is created (allocate memory) for the actual storage locations.
Here is an example of a function to allocate memory for a 2D array of int:
int ** Create2D(int **arr, int cols, int rows)
{
int space = cols*rows;
int y;
arr = calloc(space, sizeof(int));
for(y=0;y<cols;y++)
{
arr[y] = calloc(rows, sizeof(int));
}
return arr;
}
void free2DInt(int **arr, int cols)
{
int i;
for(i=0;i<cols; i++)
if(arr[i]) free(arr[i]);
free(arr);
}
Use example:
#include <ansi_c.h>
int main(void)
{
int **array=0, i, j;
array = Create2D(array, 5, 4);
for(i=0;i<5;i++)
for(j=0;j<4;j++)
array[i][j]=i*j; //example values for illustration
free2DInt(array, 5);
return 0;
}
Another point here is that it is rarely a good idea to cast the return of [m][c][re]alloc() functions
EDIT
This illustration shows my run of your code, just as you have presented it:
At the time of error, i==0 & j==0. The pointer at location paths[0][0] is uninitialized.
EDIT 2
To reallocate a 2 dimension array of int, you could use something like:
int ** Realloc2D(int **arr, int cols, int rows)
{
int space = cols*rows;
int y;
arr = realloc(arr, space*sizeof(int));
for(y=0;y<cols;y++)
{
arr[y] = calloc(rows, sizeof(int));
}
return arr;
}
And here is a test function demonstrating how it works:
#include <stdio.h>
#include <stdlib.h>
int ** Create2D(int **arr, int cols, int rows);
void free2DInt(int **arr, int cols);
int ** Realloc2D(int **arr, int cols, int rows);
int main(void)
{
int **paths = {0};
int i, j;
int col = 5;
int row = 8;
paths = Create2D(paths, col, row);
for(i=0;i<5;i++)
{
for(j=0;j<8;j++)
{
paths[i][j]=i*j;
}
}
j=0;
for(i=0;i<5;i++)
{
for(j=0;j<8;j++)
{
printf("%d ", paths[i][j]);
}
printf("\n");
}
//reallocation:
col = 20;
row = 25;
paths = Realloc2D(paths, col, row);
for(i=0;i<20;i++)
{
for(j=0;j<25;j++)
{
paths[i][j]=i*j;
}
}
j=0;
for(i=0;i<20;i++)
{
for(j=0;j<25;j++)
{
printf("%d ", paths[i][j]);
}
printf("\n");
}
free2DInt(paths, col);
getchar();
return 0;
}
The realloc() does not fail. What fails is that you haven't allocated memory for the new pointers between paths[previous_npaths] and paths[new_npaths-1], before writing to these arrays in the loop for (j = 0; j < npaths; ++j).

Resources