We know that a b-based standard positional number system uses digits,
0, 1, 2, ..., b-1. But a bijective number system uses digits, 1, 2, ..., b. So a 4-based standard number system sequence looks like,
0
1
2
3
10
11
12
13
20
21
22
23
30
31
32
33 (base-4, 16th number standard)
100 (base-4, 17th number standard)
101
.
.
.
On the other hand bijective number system for 4-based looks like,
λ (base-4, 1st number, empty-string)
1
2
3
4
11
12
13
14
21
22
23
24
31
32
33 (base-4, 16th number bijective)
34 (base-4, 17th number bijective)
41
.
.
.
Example:
34152 (in bijective base-5) = 3×54 + 4×53 + 1×52 + 5×51 + 2×1 = 2427 (in decimal).
119A (in bijective base-10, with "A" representing the digit value ten) = 1×103 + 1×102 + 9×101 + 10×1 = 1200 (in decimal).
I wonder if there is any easy way to find n'th position bijective value in same base.
For example,
lets say in base-4 5th positional value = 10 (standard) but 5th positional value = 11 (bijective). Any pseudocode is ok to understand the concept.
If a number in the standard base-n system contains no zeros, the number has the same representation as bijective base-n.
So you need to look for zeros in the standard number. When you find a zero, replace it with the maximum symbol in the bijective and decrement the element to the left.
Simple example:
10 decimal -> A bijective because 0 becomes A and 1 decrements to zero
20 decimal -> 1A bijective because 0 becomes A and 2 decrements to 1
As a special case you must handle sequences of zero.
Simple example:
200 decimal -> 19A bijective (i.e. step 1: 1A0 step 2: 19A)
You can also look at it like this
200 decimal is constructed as 2*100 + 0*10 + 0*1 = 200 decimal
For bijective you can't have zero so you'll do:
19A bijective is constructed as 1*100 + 9*10 + 10*1 = 200 decimal
To finish a bit more complex example:
110 decimal -> AA bijective (i.e. step 1: 10A step 2: AA)
This routine implements the conversion. (Which resolved to #4386427's method.) If you want the other version, where 100 (base 4 std) -> 41 (base 4 bij') then compile with -D NO_EMPTY_STRING
#include <stdio.h>
#include <string.h>
void print_be_digits(const char *prefix, const unsigned char *le_num, size_t len)
{
size_t i;
printf("%s", prefix);
for(i=0; i<len; i++)
{
printf("%d ", (int)le_num[len-i-1]);
}
printf("\n");
}
void nth_bij(int n, int k)
{
ssize_t i;
size_t std_len;
size_t bij_len;
size_t work;
unsigned char le_std_digits[256];
unsigned char le_bij_digits[256];
//convert to standard radix-k digits
work = n;
for(std_len = 0; work; std_len++)
{
le_std_digits[std_len] = work % k;
work /= k;
}
print_be_digits(" std: ", le_std_digits, std_len);
//convert standard to bij
memcpy(le_bij_digits, le_std_digits, std_len);
bij_len = std_len;
#ifdef NO_EMPTY_STRING
// Step 1: increment LSd
le_bij_digits[0]++;
#endif
// Step 2: borrow on zeros
// scan back from the end
for(i=bij_len-1; i>= 0; i--)
{
//if we find a zero, borrow, and ripple toward MSd as necessary
if(le_bij_digits[i] == 0)
{
size_t j;
//Ripple borrow toward MSd, as necessary
for(j=i+1; j<bij_len; j++)
{
le_bij_digits[j-1] = k; //k is the radix
if(--le_bij_digits[j])
{
break;
}
}//end ripple
//adjust bij_len if we rippled to the end
if(j == bij_len)
{
bij_len--;
}
}
}//end scan
print_be_digits(" bij: ", le_bij_digits, bij_len);
}
Simple driver:
int main(int argc, char *argv[])
{
printf("Test: 16 decimal (->base 4): \n");
nth_bij(16,4);
printf("\n");
printf("Test: 8 decimal (->base 2): \n");
nth_bij(8,2);
printf("\n");
printf("Test: 13 decimal (->base 2): \n");
nth_bij(13,2);
printf("\n");
printf("Test: 2427 decimal (->base 5): \n");
nth_bij(2427, 5);
printf("\n");
printf("Test: 1200 decimal (->base 10): \n");
nth_bij(1200, 10);
printf("\n");
}
Compiling for my version:
$ gcc -D NO_EMPTY_STRING bij.c
$ ./a.exe
Test: 16 decimal (->base 4):
std: 1 0 0
bij: 4 1
Test: 8 decimal (->base 2):
std: 1 0 0 0
bij: 1 2 1
Test: 13 decimal (->base 2):
std: 1 1 0 1
bij: 2 2 2
Test: 2427 decimal (->base 5):
std: 3 4 2 0 2
bij: 3 4 1 5 3
Test: 1200 decimal (->base 10):
std: 1 2 0 0
bij: 1 1 10 1
Compiling for #4386427's version:
$ gcc bij.c
$ ./a.exe
Test: 16 decimal (->base 4):
std: 1 0 0
bij: 3 4
Test: 8 decimal (->base 2):
std: 1 0 0 0
bij: 1 1 2
Test: 13 decimal (->base 2):
std: 1 1 0 1
bij: 2 2 1
Test: 2427 decimal (->base 5):
std: 3 4 2 0 2
bij: 3 4 1 5 2
Test: 1200 decimal (->base 10):
std: 1 2 0 0
bij: 1 1 9 10
Related
My class has 2 properties (String) that are two types of people's document numbers. To verify if the documents has valid numbers, a calculation is realized (verifiers digits). Below an example how is realized a consistensy of one of them:
Number: 973.345.650-02 (The punctuations must be ignored)
FIRST VERIFIER DIGIT CALCULATION
9 * 10 = 90
7 * 9 = 63
3 * 8 = 24
3 * 7 = 21
4 * 6 = 24
5 * 5 = 25
6 * 4 = 24
5 * 3 = 15
0 * 2 = 0
----------
Sum = 286
286 % 11 = 0
If rest < 2 then first digit = 0
Or if rest >= 2 then first digit = 11 - rest
In this case, rest < 2 (0), then first verifier digit = 0
SECOND VERIFIER DIGIT CALCULATION
9 * 11 = 99
7 * 10 = 70
3 * 9 = 27
3 * 8 = 24
4 * 7 = 28
5 * 6 = 30
6 * 5 = 30
5 * 4 = 20
0 * 3 = 0
0 * 2 = 0 ==> FIRST VERIFIER DIGIT
----------
Sum = 328
328 % 11 = 9
Same rule of first verifier digit
If rest < 2 then first digit = 0
Or if rest >= 2 then first digit = 11 - rest
The rest is greater than 2 (9), then second verifiter digit = 11 - 9 ==> 2
JAVA METHOD
public static boolean isValidCPF(String cpf) {
cpf = cpf.replaceAll("[./-]", "");
if (cpf.length() < 11) {
return false;
}
int equalDigits = 0;
char compareChar = cpf.charAt(0);
for (int i = 1; i <= 9; i++) {
if (compareChar == cpf.charAt(i)) {
equalDigits++;
} else {
break;
}
}
if (equalDigits == 9) {
return false;
}
int[] digit = new int[2];
int sum = 0, multiply = 2;
for (int k = 8; k <= 9; k++) {
for (int i = k; i >= 0; i--) {
sum += Character.getNumericValue(cpf.charAt(i)) * multiply++ ;
}
digit[k-8] = (sum % 11) < 2 ? 0 : 11 - (sum % 11);
sum = 0;
multiply = 2;
}
if (cpf.equals(cpf.substring(0 , 9) + digit[0] + digit[1])) {
return true;
}
return false;
}
I guess that OCL "sequence" must be used in this case (loop through digits) converting each one to Integer for calculation and using "body" in constraint, but I don't know how.
I want to apply the contraint to UML model in Papyrus (that's I know how to do).
Thanks in advance.
You must think declaratively in aggregates so to emulate
for (int i = 1; i <= 9; i++) {
if (compareChar == cpf.charAt(i)) {
equalDigits++;
} else {
break;
}
}
you might try something like
Sequence{2..10}->select(i | cpf->at(i) = compareChar)->size()
NB OCL indexes start at 1.
My array is 1D m in length. say m = 16
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
The way I actually interpret the array is n x n = m
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
I require to read the array in this manner due to the way my physical environment is set up
0 4 8 12 13 9 5 1 2 6 10 14 15 11 7 3
What I came up with works but I really don't think it is the best way to do this:
bool isFlipped = true;
int x = 0; x < m; x++
if(isFlipped)
newLine[x] = line[((n-1)-x%n)*n + x/n)]
else
newLine[x] = line[x%n*n +x/n]
if(x != 0 && x % n == 0)
isFlipped = !isFlipped
This gives me the required result but I really think there is a way to get rid of this boolean by purely using a math formula. I am stuffing this into a 8kb microcontroller and I need to conserve as much space as I can because I will have some bluetooth communication and more math going into it later on.
Edit:
Thanks to a user I got to a one line solution-ish. (the below would replace the lines in the for-loop)
c=x/n
newLine[x] = line[((c+1)%2)*((x%n)*n+c) + (c%2)*((n-1)-2*(x%n))*n ];
You should be able to utilize the fact that odd columns in the n*n matrix are read from down up, and even columns are read from up down.
A number at index x in newLine is located in column number c=floor(x/n) in the n*n matrix. c%2 is 0 for even columns and 1 for odd columns. So something like this should work:
int c = x/n;
newLine[x] = line[(x%n)*n + (c%2)*((n-1)-2*(x%n))*n + c];
I'm trying to create a function that extracts a column from a big.matrix object in Rcpp (so that it can be analyzed in cpp before bringing the results to R), but I can't figure out how to get it to recognise NA's (they are now presented as -2147483648 - as shown in my minimal example below). It would be even better if I could access the function GetMatrixCols (src/bigmemory.cpp) straight from Rcpp, but I've yet to discover a way to do that.
#include <Rcpp.h>
// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::depends(BH, bigmemory)]]
#include <bigmemory/MatrixAccessor.hpp>
#include <bigmemory/isna.hpp>
using namespace Rcpp;
//Logic for extracting column from a Big Matrix object
template <typename T>
NumericVector GetColumn_logic(XPtr<BigMatrix> pMat, MatrixAccessor<T> mat, int cn) {
NumericVector nv(pMat->nrow());
for(int i = 0; i < pMat->nrow(); i++) {
if(isna(mat[cn][i])) {
nv[i] = NA_INTEGER;
} else {
nv[i] = mat[cn][i];
}
}
return nv;
}
//' Extract Column from a Big Matrix.
//'
//' #param pBigMat A bigmemory object address.
//' #param colNum Column Number to extract. Indexing starts from zero.
//' #export
// [[Rcpp::export]]
NumericVector GetColumn(SEXP pBigMat, int colNum) {
XPtr<BigMatrix> xpMat(pBigMat);
switch(xpMat->matrix_type()) {
case 1: return GetColumn_logic(xpMat, MatrixAccessor<char>(*xpMat), colNum);
case 2: return GetColumn_logic(xpMat, MatrixAccessor<short>(*xpMat), colNum);
case 4: return GetColumn_logic(xpMat, MatrixAccessor<int>(*xpMat), colNum);
case 6: return GetColumn_logic(xpMat, MatrixAccessor<float>(*xpMat), colNum);
case 8: return GetColumn_logic(xpMat, MatrixAccessor<double>(*xpMat), colNum);
default: throw Rcpp::exception("Unknown type detected for big.matrix object!");
}
}
/*** R
bm <- bigmemory::as.big.matrix(as.matrix(reshape2::melt(matrix(c(1:4,NA,6:20),4,5))))
bigmemory:::CGetType(bm#address)
bigmemory:::GetCols.bm(bm, 3)
GetColumn(bm#address, 2)
*/
That's a great one! Stay with me for a moment:
tl;dr: It works once fixed:
R> sourceCpp("/tmp/bigmemEx.cpp")
R> bm <- bigmemory::as.big.matrix(as.matrix(reshape2::melt(matrix(c(1:4,NA,6:20),4,5))))
R> bigmemory:::CGetType(bm#address)
[1] 4
R> bigmemory:::GetCols.bm(bm, 3)
[1] 1 2 3 4 NA 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
R> GetColumn(bm#address, 2)
[1] 1 2 3 4 NA 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
R>
The trouble starts at the inside. When you create your matrix as
matrix(c(1:4,NA,6:20),4,5)
what do you get? Integer!
R> matrix(c(1:4,NA,6:20),4,5)
[,1] [,2] [,3] [,4] [,5]
[1,] 1 NA 9 13 17
[2,] 2 6 10 14 18
[3,] 3 7 11 15 19
[4,] 4 8 12 16 20
R> class(matrix(c(1:4,NA,6:20),4,5))
[1] "matrix"
R> typeof(matrix(c(1:4,NA,6:20),4,5))
[1] "integer"
R>
Not a problem per se, but a problem once you remember that the IEEE 754standard has NaN defined for floating point only (correct if I'm wrong).
The other issue is that you reflexively used NumericVector in your, but operate on integers. Now R has NaN, and even NA, for floating point and integer, but 'normal libraries' outside of R do not. And a bigmemory by design represents things outside of R, you're stuck.
The fix is simple enough: use IntegerVector (or equivalently convert your integer data on input). Below is my altered version of your code.
// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*-
#include <Rcpp.h>
// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::depends(BH, bigmemory)]]
#include <bigmemory/MatrixAccessor.hpp>
#include <bigmemory/isna.hpp>
using namespace Rcpp;
//Logic for extracting column from a Big Matrix object
template <typename T>
IntegerVector GetColumn_logic(XPtr<BigMatrix> pMat, MatrixAccessor<T> mat, int cn) {
IntegerVector nv(pMat->nrow());
for(int i = 0; i < pMat->nrow(); i++) {
if(isna(mat[cn][i])) {
nv[i] = NA_INTEGER;
} else {
nv[i] = mat[cn][i];
}
}
return nv;
}
//' Extract Column from a Big Matrix.
//'
//' #param pBigMat A bigmemory object address.
//' #param colNum Column Number to extract. Indexing starts from zero.
//' #export
// [[Rcpp::export]]
IntegerVector GetColumn(SEXP pBigMat, int colNum) {
XPtr<BigMatrix> xpMat(pBigMat);
switch(xpMat->matrix_type()) {
case 1: return GetColumn_logic(xpMat, MatrixAccessor<char>(*xpMat), colNum);
case 2: return GetColumn_logic(xpMat, MatrixAccessor<short>(*xpMat), colNum);
case 4: return GetColumn_logic(xpMat, MatrixAccessor<int>(*xpMat), colNum);
case 6: return GetColumn_logic(xpMat, MatrixAccessor<float>(*xpMat), colNum);
case 8: return GetColumn_logic(xpMat, MatrixAccessor<double>(*xpMat), colNum);
default: throw Rcpp::exception("Unknown type detected for big.matrix object!");
}
}
/*** R
bm <- bigmemory::as.big.matrix(as.matrix(reshape2::melt(matrix(c(1:4,NA,6:20),4,5))))
bigmemory:::CGetType(bm#address)
bigmemory:::GetCols.bm(bm, 3)
GetColumn(bm#address, 2)
*/
Accessing a column of a big.matrix in Rcpp is not difficult,
you can for example get an std vector, an Armadillo vector or an Eigen vector
with the following code (there may exist cleaner code):
// [[Rcpp::depends(RcppEigen, RcppArmadillo, bigmemory, BH)]]
#include <RcppArmadillo.h>
#include <RcppEigen.h>
#include <bigmemory/BigMatrix.h>
#include <bigmemory/MatrixAccessor.hpp>
using namespace Rcpp;
using namespace arma;
using namespace Eigen;
using namespace std;
// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::export]]
ListOf<IntegerVector> AccessVector(SEXP pBigMat, int j) {
XPtr<BigMatrix> xpMat(pBigMat);
MatrixAccessor<int> macc(*xpMat);
int n = xpMat->nrow();
// Bigmemory
cout << "Bigmemory:";
for (int i = 0; i < n; i++) {
cout << macc[j][i] << ' ';
}
cout << endl;
// STD VECTOR
vector<int> stdvec(macc[j], macc[j] + n);
// ARMA VECTOR
Row<int> armavec(macc[j], n); // Replace Row by Col if you want
// EIGEN VECTOR
VectorXi eigenvec(n);
memcpy(&(eigenvec(0)), macc[j], n * sizeof(int));
return(List::create(_["Std vector"] = stdvec,
_["Arma vector"] = armavec,
_["Eigen vector"] = eigenvec));
}
AccessVector(bm#address, 2) gets you:
Bigmemory:1 2 3 4 -2147483648 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
$`Std vector`
[1] 1 2 3 4 NA 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
$`Arma vector`
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15]
[1,] 1 2 3 4 NA 6 7 8 9 10 11 12 13 14 15
[,16] [,17] [,18] [,19] [,20]
[1,] 16 17 18 19 20
$`Eigen vector`
[1] 1 2 3 4 NA 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
You can see that C doesn't know about NAs but when returning to R, you keep them.
So, it depends on what operations you want to do in Rcpp on the columns. I think if you use directly Eigen or Armadillo operations, it should be OK, but you will certainly get lots of NAs in your result.
Maybe it would be clearer if you say what are these operations you want to do.
I have been trying to solve this problem.
http://www.spoj.com/problems/DIV/
for calcuating interger factors, I tried two ways
first: normal sqrt(i) iteration.
int divCount = 2;
for (int j = 2; j * j <= i ; ++j) {
if( i % j == 0) {
if( i / j == j )
divCount += 1;
else
divCount += 2;
}
}
second: Using prime factorization (primes - sieve)
for(int j = 0; copy != 1; ++j){
int count = 0;
while(copy % primes.get(j) == 0){
copy /= primes.get(j);
++count;
}
divCount *= ( count + 1);}
While the output is correct, I am getting TLE. Any more optimization can be done? Please help. Thanks
You're solving the problem from the wrong end. For any number
X = p1^a1 * p2^a2 * ... * pn^an // p1..pn are prime
d(X) = (a1 + 1)*(a2 + 1)* ... *(an + 1)
For instance
50 = 4 * 25 = 2^2 * 5^2
d(50) = (1 + 2) * (1 + 2) = 9
99 = 3^2 * 11^1
d(99) = (2 + 1) * (1 + 1) = 6
So far so good you need to generate all the numbers such that
X = p1^a1 * p2^a2 <= 1e6
such that
(a1 + 1) is prime
(a2 + 1) is prime
having a table of prime numbers from 1 to 1e6 it's a milliseconds task
It is possible to solve this problem without doing any factoring. All you need is a sieve.
Instead of a traditional Sieve of Eratosthenes that consists of bits (representing either prime or composite) arrange your sieve so each element of the array is a pointer to an initially-null list of factors. Then visit each element of the array, as you would with the Sieve of Eratosthenes. If the element is a non-null list, it is composite, so skip it. Otherwise, for each element and for each of its powers less than the limit, add the element to each multiple of the power. At the end of this process you will have a list of prime factors of the number. That wasn't very clear, so let me give an example for the numbers up to 20. Here's the array, initially empty:
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Now we sieve by 2, adding 2 to each of its multiples:
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2 2 2 2 2 2 2 2 2 2
Since we also sieve by powers, we add 2 to each multiple of 4:
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2
And likewise, by each multiple of 8 and 16:
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2
2 2
2
Now we're finished with 2, so we go to the next number, 3. The entry for 3 is null, so we sieve by 3 and its power 9:
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2
2 2
2
3 3 3 3 3 3
3 3
Then we sieve by 5, 7, 11, 13, 17 and 19:
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2
2 2
2
3 3 3 3 3 3
3 3
5 5 5 5
7 7
11
13
17
19
Now we have a list of all the prime factors of all the numbers less than the limit, computed by sieving rather than factoring. It's easy then to calculate the number of divisors by scanning the lists; count the number of occurrences of each factor in the list, add 1 to each total, and multiply the results. For instance, 12 has 2 factors of 2 and 1 factor of 3, so take (2+1) * (1+1) = 3 * 2 = 6, and indeed 12 has 6 factors: 1, 2, 3, 4, 6 and 12.
The final step is to check if the number of divisors has exactly two factors. That's easy: just look at the list of prime divisors and count them.
Thus, you have solved the problem without doing any factoring. That ought to be very fast, just a little bit slower than a traditional Sieve of Eratosthenes and very much faster than factoring each number to compute the number of divisors.
The only potential problem is space consumption for the lists of prime factors. But you shouldn't worry too much about that; the largest list will have only 19 factors (since the smallest factor is 2, and 2^20 is greater than your limit), and 78498 of the lists will have only a single factor (the primes less than a million).
Even though the above mentioned problem doesn't require calculating number of divisors, It still can be solved by calculating d(N) (divisors of N) within the time limit (0.07s).
The idea is to pretty simple. Keep track of smallest prime factor f(N) of every number. This can be done by standard prime sieve. Now, for every number i keep dividing it by f(i) and increment the count till i = 1. You now have set of prime counts for each number i.
int d[MAX], f[MAX];
void sieve() {
for (int i = 2; i < MAX; i++) {
if (!f[i]) {
f[i] = i;
for (int j = i * 2; j < MAX; j += i) {
if (!f[j]) f[j] = i;
}
}
d[i] = 1;
}
for (int i = 1; i < MAX; i++) {
int k = i;
while (k != 1) {
int s = 0, fk = f[k];
while (k % fk == 0) {
k /= fk; s++;
}
d[i] *= (s + 1);
}
}
}
Once, d(N) is figured out, rest of the problem becomes much simpler. Keeping a smallest prime factor of every number also helps to solve lots of other problems.
I have number of processors and one array, and each processor fills their work into, one dimensional array like:
dense_process_array for process 1:
|process1|0000000000000|
dense_process_array for process 2:
|000000|process2|000000|
each process fills their interval, then I want to all processors have others results into same array.
Process 1 => dense_process_array |process1|process2|.....|processN|
Process 2 ... Process N
(like all2all bcast) Therefore, Every process calls this function:
void doCommunication(int id, int numprocs, int start_point, int end_point) {
int size_of_length = end_point - start_point + 1;
MPI_Scatter(dense_process_array+start_point, size_of_length, MPI_DOUBLE, dense _process_array +start_point, size_of_length, MPI_DOUBLE, id, MPI_COMM_WORLD;
}
But, in the end when I looked my array from any process, I seen that it can not get results of other processes, can you suggest anything?
not: I'm new in MPI, and basicly I want to all2all bcast.
I believe you're looking for MPI_Allgather:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
void printdata(int size, int rank, int n, int *data) {
printf("Rank %d\n",rank);
for (int j=0; j<size*n; j++)
printf("%d ",data[j]);
printf("\n");
}
int main(int argc, char **argv) {
const int n=3;
int ierr, rank, size;
int *datain, *dataout;
ierr = MPI_Init(&argc, &argv);
ierr|= MPI_Comm_size(MPI_COMM_WORLD,&size);
ierr|= MPI_Comm_rank(MPI_COMM_WORLD,&rank);
datain = (int *)malloc(n*size*sizeof(int));
dataout = (int *)malloc(n*size*sizeof(int));
for (int i=0; i<n*size; i++)
datain[i]=9;
for (int i=0; i<n; i++)
datain[rank*n+i]=rank;
if (rank == 0) printf("Before:\n");
printdata(size, rank, n, datain);
MPI_Allgather(&(datain[rank*n]), n, MPI_INT, dataout, n, MPI_INT, MPI_COMM_WORLD);
if (rank == 0) printf("After:\n");
printdata(size, rank, n, dataout);
free(datain);
free(dataout);
MPI_Finalize();
return 0;
}
Running gives
$ mpirun -np 3 ./allgather
Before:
Rank 0
0 0 0 9 9 9 9 9 9
Rank 1
9 9 9 1 1 1 9 9 9
Rank 2
9 9 9 9 9 9 2 2 2
After:
Rank 0
0 0 0 1 1 1 2 2 2
Rank 1
0 0 0 1 1 1 2 2 2
Rank 2
0 0 0 1 1 1 2 2 2