2

I'm trying to use the Rcpp package in R. I have this c++ code to use the D'Hondt method over a vector of votes:

#include <iostream>
#include <vector>
#include<Rcpp.h>

// original: http://www.brainum.es/code/ccplusplus/sistema-d-hondt-en-c

struct DhondtParty {
    int votes, seats;
    bool ok;
};

class Dhondt {
    public:
        DhondtParty* parties; 
        double minimun;
        int votes,
        numparties, 
        blank_votes,
        esc;
    Dhondt(int total,int arrayMem) {
        this->esc = total;
        this->numparties = 0; this->minimun = 0; this->blank_votes = 0;
        this->parties = new DhondtParty[arrayMem];
    }
    void addblank(int pvotes) {
                this->votes += pvotes;
                this->blank_votes += pvotes;
    }
    void addparty(int partyvotes) {
        DhondtParty party;
        party.seats = 0;
        party.votes = partyvotes;
        party.ok = false;
        this->parties[this->numparties] = party; 
        this->votes = this->votes+partyvotes; 
        this->numparties++; 
    }
    void setminimun(double minimun) {
        this->minimun = minimun;
    }
    void results() {
        int i,z,mparty; 
        for(z=0;this->parties[z].votes;z++) {
            if((double)this->parties[z].votes/(double)this->votes >= (double)this->minimun/100.0) this->parties[z].ok = true;

        }
        for(i=1;i<=this->esc;i++) { 
            mparty = -1; 
            for(z=0;this->parties[z].votes;z++) { 
                if(this->parties[z].ok && (this->parties[z].votes/(this->parties[z].seats+1) > this->parties[mparty].votes/(this->parties[mparty].seats+1) || mparty < 0)) { 
                  mparty = z; 
                }
            }
            this->parties[mparty].seats++; 

        }
    }

};


// [[Rcpp::export]]
Rcpp::NumericVector aplicaleydHont_a(){

  Dhondt d(100,6); // Se llama a la clase, y se guarda en la variable d.
  // Añadimos los partidos:
  d.addparty(23);
  d.addparty(21);
  d.addparty(15);
  d.addparty(11);
  d.addparty(1);
  d.addparty(18);


  d.addblank(3); // votos en blanco
  d.setminimun(3); // En %
  d.results(); // Procesamos
  Rcpp::NumericVector escas(d.numparties);
  for(int i = 0; i < d.numparties; ++i){
    std::cout << d.parties[i].seats << std::endl;
    escas[i] = d.parties[i].seats;
  }
  return escas;
}


// [[Rcpp::export]]
Rcpp::NumericVector aplicaleydHont(int v){

  Dhondt d(100,6); // Se llama a la clase, y se guarda en la variable d.
  // Añadimos los partidos:
  d.addparty(23);
  d.addparty(21);
  d.addparty(15);
  d.addparty(11);
  d.addparty(1);
  d.addparty(18);


  d.addblank(3); // votos en blanco
  d.setminimun(3); // En %
  d.results(); // Procesamos
  Rcpp::NumericVector escas(d.numparties);
  for(int i = 0; i < d.numparties; ++i){
    std::cout << d.parties[i].seats << std::endl;
    escas[i] = d.parties[i].seats;
  }
  return escas;
}

As you can see I have a class and 2 same functions, the first one without any parameter and the second one with one parameter. The thing is that when I use the function with a parameter (at the end I want to pass the votes in a vector parameter) I don't get any result.

The R code that I use to call this functions:

library(Rcpp)

Rcpp::sourceCpp('D:/Elecciones/modeloR_espa16/leydHont.cpp')


aplicaleydHont_a()
aplicaleydHont(1)

And I obtain this result:

> aplicaleydHont_a()
35
21
15
11
0
18
[1] 35 21 15 11  0 18
> aplicaleydHont(1)
0
0
0
0
0
0
[1] 0 0 0 0 0 0

Anyone know why I can't pass parameters to these functions? Is there some issue with the integration of Rcpp and the c++ classes?

Thanks!!

Xevi

1 Answer 1

2

When I process your file I get the following output:

dHondt.cpp: In function ‘Rcpp::NumericVector aplicaleydHont_a()’:
dHondt.cpp:35:29: warning: ‘d.Dhondt::votes’ is used uninitialized in this function [-Wuninitialized]
         this->votes = this->votes+partyvotes;
                       ~~~~~~^~~~~
dHondt.cpp: In function ‘Rcpp::NumericVector aplicaleydHont(int)’:
dHondt.cpp:35:29: warning: ‘d.Dhondt::votes’ is used uninitialized in this function [-Wuninitialized]
         this->votes = this->votes+partyvotes;
                       ~~~~~~^~~~~

> 
aplicaleydHont_a()
0
0
0
0
0
0
[1] 0 0 0 0 0 0

> 
aplicaleydHont(1)
0
0
0
0
0
0
[1] 0 0 0 0 0 0

After adding

this->votes = 0;

to the constructor I get:

> 
aplicaleydHont_a()
35
21
15
11
0
18
[1] 35 21 15 11  0 18

> 
aplicaleydHont(1)
35
21
15
11
0
18
[1] 35 21 15 11  0 18

Notes:

  • Use Rcpp::Rcout instead of std::cout.
  • I would use initialization lists in the constructor.
  • I would use vector instead of naked arrays.
  • If you need a naked array, then you need a destructor.

BTW, searching for “D’Hondt” on CRAN produces several results. Did you check that these aren’t sufficient?

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your answer and fo the notes! Only one last question: Where do you get the log that warns you of the uninitialitzed variable? When I execute Rcpp::sourceCpp('mfile') I don't get that warning.
@Xevi That’s exactly where I get these warnings. Note that I have added -Wall -pedantic to the compiler flags via ~/.R/Makevars.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.