Rcpp: я не могу передать аргумент функции c ++ - PullRequest
0 голосов
/ 01 декабря 2018

Я пытаюсь использовать пакет Rcpp в R. У меня есть этот код c ++ для использования метода D'Hondt над вектором голосов:

#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;
}

Как видите, у меня есть класси 2 одинаковые функции: первая без какого-либо параметра и вторая с одним параметром.Дело в том, что когда я использую функцию с параметром (в конце я хочу передать голоса в векторный параметр), я не получаю никакого результата.

Код R, который я использую для вызова этогофункции:

library(Rcpp)

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


aplicaleydHont_a()
aplicaleydHont(1)

И я получаю этот результат:

> 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

Кто-нибудь знает, почему я не могу передать параметры этим функциям?Есть ли какая-то проблема с интеграцией Rcpp и классов c ++?

Спасибо !!

Xevi

1 Ответ

0 голосов
/ 01 декабря 2018

Когда я обрабатываю ваш файл, я получаю следующий вывод:

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

После добавления

this->votes = 0;

в конструктор я получаю:

> 
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

Примечания:

  • Используйте Rcpp::Rcout вместо std::cout.
  • Я бы использовал списки инициализации в конструкторе.
  • Я бы использовал vector вместо голыхмассивы.
  • Если вам нужен голый массив, то вам нужен деструктор.

Кстати, поиск «D'Hondt» в CRAN дает несколько результатов.Вы проверили, что этого недостаточно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...