Arrangement of n objects (Permutation with duplicates) - algorithm

I am looking for a fast implementation of the "arrangement" algorithm (permutation with duplicates).
Given N objects (A in quantity a, B in quantity b, ...), generate all the possible combinations.
Exemple:
Arrangement("AAA", "B", "CC") would return :
"AAABCC" "AABACC" "AABCAC" "AABCCA" "ABAACC" "ABACAC" "ABACCA" "ABCAAC"
"ABCACA" "ABCCAA" "BAAACC" "BAACAC" "BAACCA" "BACAAC" "BACACA" "BACCAA"
"BCAAAC" "BCAACA" "BCACAA" "BCCAAA" "AAACBC" "AACABC" "AACBAC" "AACBCA"
"ACAABC" "ACABAC" "ACABCA" "ACBAAC" "ACBACA" "ACBCAA" "CAAABC" "CAABAC"
"CAABCA" "CABAAC" "CABACA" "CABCAA" "CBAAAC" "CBAACA" "CBACAA" "CBCAAA"
"AAACCB" "AACACB" "AACCAB" "AACCBA" "ACAACB" "ACACAB" "ACACBA" "ACCAAB"
"ACCABA" "ACCBAA" "CAAACB" "CAACAB" "CAACBA" "CACAAB" "CACABA" "CACBAA"
"CCAAAB" "CCAABA" "CCABAA" "CCBAAA"
(Code in C, C# or Pascal if possible)
Thanks in advance
Philippe

If you can use C++, it's already provided in the standard library:
#include <algorithm>
#include <string>
#include <iostream>
int main() {
std::string a("AAABCC");
do {
std::cout << a << "\t";
} while (std::next_permutation(a.begin(), a.end()));
return 0;
}
Edit: the output from this is:
AAABCC AAACBC AAACCB AABACC AABCAC AABCCA AACABC AACACB AACBAC AACBCA
AACCAB AACCBA ABAACC ABACAC ABACCA ABCAAC ABCACA ABCCAA ACAABC ACAACB
ACABAC ACABCA ACACAB ACACBA ACBAAC ACBACA ACBCAA ACCAAB ACCABA ACCBAA
BAAACC BAACAC BAACCA BACAAC BACACA BACCAA BCAAAC BCAACA BCACAA BCCAAA
CAAABC CAAACB CAABAC CAABCA CAACAB CAACBA CABAAC CABACA CABCAA CACAAB
CACABA CACBAA CBAAAC CBAACA CBACAA CBCAAA CCAAAB CCAABA CCABAA CCBAAA
For anybody who can't use C++, Mark Nelson wrote an article in the C/C++ User's Journal a few years ago that might be helpful.

Related

Modifying BOOST_PP_SEQ

I have some sequence: (a)(1)(b)(2)(c)(3) and I want to expand it in: a_b_c, what solutions? I tried BOOST_PP_SEQ_FOLD_LEFT vs BOOST_PP_SEQ_FILTER but unsuccessfully, it's was: a1b2c3 ...
Help)
You could do something like this (I can't guarantee it's the best approach):
#define DO_CONCAT_WITH_UNDERSCORE(__,STATE,ELEM) BOOST_PP_CAT(STATE,BOOST_PP_CAT(_,ELEM))
#define DO_FILTER_POSITION(_,__,INDEX,ELEM) BOOST_PP_IF(BOOST_PP_MOD(INDEX,2),BOOST_PP_EMPTY(),(ELEM)) //IF IT'S ODD ADD NOTHING, IF IT'S EVEN ADD THE CURRENT ELEM IN PARENS
#define TAKE_EVEN_POSITIONS(SEQ) BOOST_PP_SEQ_FOR_EACH_I(DO_FILTER_POSITION,_,SEQ)
#define TAKE_EVEN_POSITIONS_AND_CONCAT_HELPER(FILTERED_SEQ) BOOST_PP_SEQ_FOLD_LEFT(DO_CONCAT_WITH_UNDERSCORE,BOOST_PP_SEQ_HEAD(FILTERED_SEQ),BOOST_PP_SEQ_TAIL(FILTERED_SEQ))
#define TAKE_EVEN_POSITIONS_AND_CONCAT(SEQ) TAKE_EVEN_POSITIONS_AND_CONCAT_HELPER(TAKE_EVEN_POSITIONS(SEQ))
Running on Wandbox

PETSC time stepping under mpirun mode

Dear all,
I'm a freshman in learning PETSC. I wrote a very simple 1D diffusion problem code based on PETSC library(Just simple FDM code). I want to use PETSC's parallel solver in each time step. Here is the pseudo code:
Initial(C0);
for(timestep=0;timestep<MaxTimeStep;timestep++)
{
Assemble(A,C,F); // Assemble system's A*C=F matrix and vector
KSP.solve(A,C,F); // Use PETSC's ksp solver to solve A*C=F
// I just want to make the solve step paralleled
// other part don't need to be paralleled
C0=C; // Update
SaveResult(C0); // Output the result C0
}
This code works very fine under sequential mode(the matrix and vector are both based on the MPI type), but when I try to use mpirun -np 4 ./a.out, the result is totally wrong. I guess mpirun make the timestep loop also paralleled, but I'm not sure about it.
So, my problem are:
How to use PETSC's parallel solver inside a loop, or in other words, how to use parallel solver or mpirun inside a sequential time stepping?
Is it possible that I can use mpirun -np 4 ./myapp to just parallel the solver, but for the time stepping and result output,they are still sequential? In the simulation, time stepping and result output must be executed one by one, so I just need to parallel the solver, not the whole program.
Thank you!
#include "petscksp.h"
void PrintToVTU(PetscInt k,PetscReal dx,Vec u);
int main(int argc,char **args)
{
Vec u,u0;
Mat A;
KSP ksp;
PetscRandom rctx;
PetscReal norm;
PetscInt ne;
PetscReal Length,dx,D;
PetscReal Ca,Cb,alpha;
PetscReal T,dt,ti;
PetscInt i,j,Ii,J,Istart,Iend,m,n,its;
PetscBool flg=PETSC_FALSE;
PetscScalar v;
printf("Input the Length:");
scanf("%f",&Length);
printf("Input the element number:");
scanf("%d",&ne);
printf("Input the Ca,Cb and D:");
scanf("%f %f %f",&Ca,&Cb,&D);
printf("Input dt and T:");
scanf("%f %f",&dt,&T);
n=ne+1;m=n;
dx=Length/ne;
alpha=dt*D/(dx*dx);
#if defined(PETSC_USE_LOG)
PetscLogStage stage;
#endif
static char help[] = "Solves a linear system in parallel with
KSP.\n\
Iput parameters include:\n-random_exact_sol : use a random exact
solution vector\n\
-view_exact_sol : write exact solution vector to stdout\n\
-m <mesh_x> : number of mesh points in x-direction\n\
-n <mesh_n> : number of mesh points in y-direction\n\n";
PetscInitialize(&argc,&args,(char*)0,help);
PetscOptionsGetInt(NULL,NULL,"-m",&m,NULL);
PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);
printf("m=%d\tn=%d\n",m,n);
// Create Matrix
MatCreate(PETSC_COMM_WORLD,&A);
MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,m,n);
MatSetFromOptions(A);
MatMPIAIJSetPreallocation(A,5,NULL,5,NULL);
MatSeqAIJSetPreallocation(A,5,NULL);
MatSeqSBAIJSetPreallocation(A,1,5,NULL);
// Create Vector
VecCreate(PETSC_COMM_WORLD,&u0);
VecSetSizes(u0,PETSC_DECIDE,m);
VecSetFromOptions(u0);
VecDuplicate(u0,&u);
MatGetOwnershipRange(A,&Istart,&Iend);
PetscLogStageRegister("Assembly",&stage);
PetscLogStagePush(stage);
for(Ii=Istart;Ii<Iend;Ii++)
{
if(Ii==0)
{
v=1.0+2.0*alpha;J=Ii;
MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);
v=-2.0*alpha;J=Ii+1;
MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);
}
else if(Ii==n-1)
{
v=-2.0*alpha;J=Ii-1;
MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);
v=1.0+2.0*alpha;J=Ii;
MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);
}
else
{
v=-alpha;J=Ii-1;
MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);
v=1.0+2.0*alpha;J=Ii;
MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);
v=-alpha;J=Ii+1;
MatSetValues(A,1,&Ii,1,&J,&v,ADD_VALUES);
}
if(Ii<=m/2)
{
VecSetValues(u0,1,&Ii,&Ca,ADD_VALUES);
}
else
{
VecSetValues(u0,1,&Ii,&Cb,ADD_VALUES);
}
}
MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);
VecAssemblyBegin(u0);
VecAssemblyEnd(u0);
KSPCreate(PETSC_COMM_WORLD,&ksp);
KSPSetOperators(ksp,A,A);
KSPSetFromOptions(ksp);
dt=1.0;T=2.0;i=0;
PrintToVTU(i,dx,u0);
printf("Hello\n");
for(ti=0.0;ti<=T;ti+=dt)
{
i+=1;
KSPSolve(ksp,u0,u);
VecCopy(u,u0);
PrintToVTU(i,dx,u0);
}
}

Understanding crc32

I try to understand the computation of crc32. It's new to me, so the question is a basic one. With the following code I have two different ways of computing the CRC32 sum. They should (in theory) be the same, but they differ. What am I doing wrong?
The Go stdlib implementation (what a surprise) seems to be correct, but I can't find the error in my implementation.
https://play.golang.org/p/QJH2K3IQEj
package main
import (
"fmt"
"hash/crc32"
)
func main() {
message := []byte("hello")
// Is this the correct polynomial table? This is the table from
// http://gnuradio.org/redmine/projects/gnuradio/repository/revisions/1cb52da49230c64c3719b4ab944ba1cf5a9abb92/entry/gr-digital/lib/digital_crc32.cc
tbl := [256]uint32{0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9,
0x130476DC, 0x17C56B6B, 0x1A864DB2, 0x1E475005,
0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61,
0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD,
0x4C11DB70, 0x48D0C6C7, 0x4593E01E, 0x4152FDA9,
0x5F15ADAC, 0x5BD4B01B, 0x569796C2, 0x52568B75,
0x6A1936C8, 0x6ED82B7F, 0x639B0DA6, 0x675A1011,
0x791D4014, 0x7DDC5DA3, 0x709F7B7A, 0x745E66CD,
0x9823B6E0, 0x9CE2AB57, 0x91A18D8E, 0x95609039,
0x8B27C03C, 0x8FE6DD8B, 0x82A5FB52, 0x8664E6E5,
0xBE2B5B58, 0xBAEA46EF, 0xB7A96036, 0xB3687D81,
0xAD2F2D84, 0xA9EE3033, 0xA4AD16EA, 0xA06C0B5D,
0xD4326D90, 0xD0F37027, 0xDDB056FE, 0xD9714B49,
0xC7361B4C, 0xC3F706FB, 0xCEB42022, 0xCA753D95,
0xF23A8028, 0xF6FB9D9F, 0xFBB8BB46, 0xFF79A6F1,
0xE13EF6F4, 0xE5FFEB43, 0xE8BCCD9A, 0xEC7DD02D,
0x34867077, 0x30476DC0, 0x3D044B19, 0x39C556AE,
0x278206AB, 0x23431B1C, 0x2E003DC5, 0x2AC12072,
0x128E9DCF, 0x164F8078, 0x1B0CA6A1, 0x1FCDBB16,
0x018AEB13, 0x054BF6A4, 0x0808D07D, 0x0CC9CDCA,
0x7897AB07, 0x7C56B6B0, 0x71159069, 0x75D48DDE,
0x6B93DDDB, 0x6F52C06C, 0x6211E6B5, 0x66D0FB02,
0x5E9F46BF, 0x5A5E5B08, 0x571D7DD1, 0x53DC6066,
0x4D9B3063, 0x495A2DD4, 0x44190B0D, 0x40D816BA,
0xACA5C697, 0xA864DB20, 0xA527FDF9, 0xA1E6E04E,
0xBFA1B04B, 0xBB60ADFC, 0xB6238B25, 0xB2E29692,
0x8AAD2B2F, 0x8E6C3698, 0x832F1041, 0x87EE0DF6,
0x99A95DF3, 0x9D684044, 0x902B669D, 0x94EA7B2A,
0xE0B41DE7, 0xE4750050, 0xE9362689, 0xEDF73B3E,
0xF3B06B3B, 0xF771768C, 0xFA325055, 0xFEF34DE2,
0xC6BCF05F, 0xC27DEDE8, 0xCF3ECB31, 0xCBFFD686,
0xD5B88683, 0xD1799B34, 0xDC3ABDED, 0xD8FBA05A,
0x690CE0EE, 0x6DCDFD59, 0x608EDB80, 0x644FC637,
0x7A089632, 0x7EC98B85, 0x738AAD5C, 0x774BB0EB,
0x4F040D56, 0x4BC510E1, 0x46863638, 0x42472B8F,
0x5C007B8A, 0x58C1663D, 0x558240E4, 0x51435D53,
0x251D3B9E, 0x21DC2629, 0x2C9F00F0, 0x285E1D47,
0x36194D42, 0x32D850F5, 0x3F9B762C, 0x3B5A6B9B,
0x0315D626, 0x07D4CB91, 0x0A97ED48, 0x0E56F0FF,
0x1011A0FA, 0x14D0BD4D, 0x19939B94, 0x1D528623,
0xF12F560E, 0xF5EE4BB9, 0xF8AD6D60, 0xFC6C70D7,
0xE22B20D2, 0xE6EA3D65, 0xEBA91BBC, 0xEF68060B,
0xD727BBB6, 0xD3E6A601, 0xDEA580D8, 0xDA649D6F,
0xC423CD6A, 0xC0E2D0DD, 0xCDA1F604, 0xC960EBB3,
0xBD3E8D7E, 0xB9FF90C9, 0xB4BCB610, 0xB07DABA7,
0xAE3AFBA2, 0xAAFBE615, 0xA7B8C0CC, 0xA379DD7B,
0x9B3660C6, 0x9FF77D71, 0x92B45BA8, 0x9675461F,
0x8832161A, 0x8CF30BAD, 0x81B02D74, 0x857130C3,
0x5D8A9099, 0x594B8D2E, 0x5408ABF7, 0x50C9B640,
0x4E8EE645, 0x4A4FFBF2, 0x470CDD2B, 0x43CDC09C,
0x7B827D21, 0x7F436096, 0x7200464F, 0x76C15BF8,
0x68860BFD, 0x6C47164A, 0x61043093, 0x65C52D24,
0x119B4BE9, 0x155A565E, 0x18197087, 0x1CD86D30,
0x029F3D35, 0x065E2082, 0x0B1D065B, 0x0FDC1BEC,
0x3793A651, 0x3352BBE6, 0x3E119D3F, 0x3AD08088,
0x2497D08D, 0x2056CD3A, 0x2D15EBE3, 0x29D4F654,
0xC5A92679, 0xC1683BCE, 0xCC2B1D17, 0xC8EA00A0,
0xD6AD50A5, 0xD26C4D12, 0xDF2F6BCB, 0xDBEE767C,
0xE3A1CBC1, 0xE760D676, 0xEA23F0AF, 0xEEE2ED18,
0xF0A5BD1D, 0xF464A0AA, 0xF9278673, 0xFDE69BC4,
0x89B8FD09, 0x8D79E0BE, 0x803AC667, 0x84FBDBD0,
0x9ABC8BD5, 0x9E7D9662, 0x933EB0BB, 0x97FFAD0C,
0xAFB010B1, 0xAB710D06, 0xA6322BDF, 0xA2F33668,
0xBCB4666D, 0xB8757BDA, 0xB5365D03, 0xB1F740B4}
crc := uint32(0xffffffff)
// different result
for _, v := range message {
crc = tbl[v^(byte(crc>>24)&0xff)] ^ (crc << 8)
}
crc = ^crc
fmt.Printf("%10d == 0x%x\n", crc, crc) // 422667581 == 0x1931653d
// same as http://zorc.breitbandkatze.de/crc.html
chk := crc32.ChecksumIEEE(message)
fmt.Printf("%10d == 0x%x\n", chk, chk) // 907060870 == 0x3610a686
}
Edit (from a comment below): I understand that the source code of Go's crc32 and mine are different. But why is my implementation giving a different result? The table I am using has the same starting polynome (from the wiki page for CRC-32) as Go's implementation (0x04C11DB7), except that Go uses the reversed polynome and therfore a different algorithm is not surprising. "My" algorithm comes from various different C/C++ sources, such as the one linked in the source.
First, it seem that you are not using the right table (or at least the same than the golang standard library): you can check it simply by comparing your table to the one available in the crc32 package. Here is a playground example.
Then, you algorithm is also wrong. To be honest, I didn't even tried to check whether you put the right values at the right places, but simply dug out the code used by crc32.Checksum. Here is a fixed version of your algorithm:
crc := uint32(0xffffffff)
for _, v := range message {
crc = tbl[byte(crc)^v] ^ (crc >> 8)
}
return ^crc
As you see, the in-loop calculation is a bit different. you can see it in action with the crc32.IEEE polynominal table here.

Setting up Rcpp Armadillo in windows with Rstudio

I am trying to set up RcppArmadillo in my windows system with Rstudio. I have successfully installed RcppArmadillo with the command
install.packages("RcppArmadillo")
in R console.
But when I try to compile a c++ code with RcppArmadillo dependency I get a error like
g++ -m64 -I"C:/PROGRA~1/R/R-30~1.3/include" -DNDEBUG -I"C:/PROGRA~1/R/R-30~1.3/library/Rcpp/include" -I"d:/RCompile/CRANpkg/extralibs64/local/include" -O2 -Wall -mtune=core2 -c colrowStat.cpp -o colrowStat.o colrowStat.cpp:5:26: fatal error: RcppArmadillo.h: No such file or directory compilation terminated. make: *** [colrowStat.o] Error 1 Warning message: running command 'make -f "C:/PROGRA~1/R/R-30~1.3/etc/x64/Makeconf" -f "C:/PROGRA~1/R/R-30~1.3/share/make/winshlib.mk" SHLIB_LDFLAGS='$(SHLIB_CXXLDFLAGS)' SHLIB_LD='$(SHLIB_CXXLD)' SHLIB="sourceCpp_38187.dll" WIN=64 TCLBIN=64 OBJECTS="colrowStat.o"' had status 2
But the header files are available in path_to_my_documents/R/win-libraries/3.0/RcppArmadillo/Include
I think the include path for compilation dose not have this path. I don't how to add this folder to the path. I greatly appreciate any help with this problem.
You are doing it wrong. There are many ways to do it, and we documented several of them. What you do here is not one of them.
Try this instead and go from there:
R> library(Rcpp)
R> cppFunction("arma::mat op(arma::vec x) { return(x*x.t()); }",
+ depends="RcppArmadillo")
R> op(1:2)
[,1] [,2]
[1,] 1 2
[2,] 2 4
R>
This is one of the basic examples: take a vector, multiply it by its transpose and return the result outer product matrix.
What you ultimately want is a package, and for that you could do much worse than starting by RcppArmadillo.package.skeleton().
Your question is short on details, but if you are on a Windows machine and are using RStudio, then here is a fully reproducible example on how to use RcppArmadillo without using the inline package, which is not ideal except for very short functions.
As Dirk has pointed out, this advice is available elsewhere -- the Rcpp* ecosystem is bizarrely well-documented, but this might help a novice.
0. Preliminaries:
You should have the following installed:
Rtools
R package devtools
R package Rcpp
R package RcppArmadillo
1. C++ code:
The example is a simple one of computing the OLS estimator for a linear regression model. Here is what the C++ file, with one function (fnLinRegRcpp) that takes the design matrices as inputs and produces the OLS coefficient estimates and the model residuals as an Rcpp List looks like:
// LinearRegression.cpp
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
using namespace arma; // use the Armadillo library for matrix computations
using namespace Rcpp;
// [[Rcpp::export]]
List fnLinRegRcpp(vec vY, mat mX) {
// compute the OLS estimator & model residuals
vec vBeta = solve(mX.t()*mX, mX.t()*vY);
vec vResid = vY - mX * vBeta;
// construct the return object
List ret;
ret["beta"] = vBeta;
ret["resid"] = vResid;
return ret;
}
// END
Note the use of Rcpp attributes:
// [[Rcpp::depends(RcppArmadillo)]]
to indicate library dependencies on the Armadillo library.
2. R code
Here is an example of the compilation of the C++ code using the sourceCpp function, together with an example of the use of the function, and a comparison of the output to the built-in lm.fit function.
# LinearRegression.R
library(devtools)
library(Rcpp)
library(RcppArmadillo)
Rcpp::sourceCpp("code/LinearRegression.cpp",
showOutput = TRUE,
rebuild = FALSE)
# generate some sample data
iK = 4
iN = 100
mX = cbind(1, matrix(rnorm(iK*iN), iN, iK))
vBeta0 = c(2, 3.5, 0.11, 6.33, 23)
vY = rnorm(iN, mean = mX %*% vBeta0)
# test the function
linReg1 = fnLinRegRcpp(vY, mX)
linReg1$beta # coefficient estimates
# compare the results to the built-in lm.fit function
lm.fit(y = vY, x = mX)$coef # coefficient estimates
# END

interval map in C++

I need to map some intervals (actually these are intervals of addresses) to object ids.
I tried to use boost's interval_map, the example looks very pretty, it easily enumerates all intervals like:
while(it != party.end())
{
interval<ptime>::type when = it->first;
// Who is at the party within the time interval 'when' ?
GuestSetT who = (*it++).second;
cout << when << ": " << who << endl;
}
Which outputs:
----- History of party guests -------------------------
[2008-May-20 19:30:00, 2008-May-20 20:10:00): Harry Mary
[2008-May-20 20:10:00, 2008-May-20 22:15:00): Diana Harry Mary Susan
[2008-May-20 22:15:00, 2008-May-20 23:00:00): Diana Harry Mary Peter Susan
[2008-May-20 23:00:00, 2008-May-21 00:00:00): Diana Peter Susan
[2008-May-21 00:00:00, 2008-May-21 00:30:00): Peter
but it cannot do something like this:
interval<ptime>::type when =
interval<ptime>::closed(
time_from_string("2008-05-20 22:00"),
time_from_string("2008-05-20 22:01"));
GuestSetT who = party[when];
cout << when << ": " << who << endl;
it outputs: error: no match for 'operator[]' in 'party[when]'
it looks strange, since the main function of map is in operator[]
so I cannot get information "who were at the party at a given time"
Is there a ready-to-use solution for this problem?
It's somewhat counter-intuitive, but the () operator is what you're looking for. From the docs, operator() is defined as "Return[ing] the mapped value for a key x. The operator is only available for total maps."
Source: http://www.boost.org/doc/libs/1_54_0/libs/icl/doc/html/boost_icl/function_reference/selection.html

Resources