Commit 768a05e2 authored by Antoine Lucas's avatar Antoine Lucas
Browse files

improve operator[]

parent c0c81844
......@@ -26,7 +26,7 @@
using namespace std;
#include <Rmath.h>
#include "extract_matrix.h"
/* Globals variables */
static gmp_randstate_t seed_state;
......@@ -446,57 +446,17 @@ SEXP biginteger_get_at(SEXP a, SEXP i)
// also called from matrix_get_at_z(.) in ./extract_matrix.cc :
bigvec bigintegerR::biginteger_get_at_C(bigvec va, SEXP ind)
{
vector<int> v_ind = bigintegerR::create_int(ind);
vector<int> v_ind = extract_gmp_R::indice_get_at(va.size(),ind);
bigvec result;
// logical: ind = true/false
if (TYPEOF(ind) == LGLSXP) {
for (unsigned int i = 0; i < va.size(); ++i)
if (v_ind[i%v_ind.size()])
{
//std::cout << "cas LOGIC "<< std::endl;
result.push_back(va[i]);
}
return result;
}
else {
std::remove(v_ind.begin(), v_ind.end(), 0); // remove all zeroes from ind
if (v_ind.empty())
return bigvec();
// case: a[-ind]
if (v_ind[0] < 0) {
//std::cout << "cas ngatif" << std::cout;
for (vector<int>::iterator it = v_ind.begin(); it != v_ind.end(); ++it)
if (*it > 0)
error(_("only 0's may mix with negative subscripts"));
else if (-(*it)-1 >= (int)va.size())
error(_("subscript out of bounds"));
// TODO: This is optimized for large va.size and small v_ind.size.
// Maybe add a condition to use a different approach for large v_ind's
result.value.reserve(va.size()-v_ind.size());
for (int i = 0; i < (int)va.size(); ++i)
if (find(v_ind.begin(), v_ind.end(), -i-1) == v_ind.end())
{
result.push_back(va[i]);
}
}
else {
// standard case: a[ind] with ind: integers
result.value.reserve(v_ind.size());
for (vector<int>::iterator it = v_ind.begin(); it != v_ind.end(); ++it) {
if (*it <= 0)
error(_("only 0's may mix with negative subscripts"));
if (*it <= (int)va.size())
{
//std::cout << "on sort " << va.value[(*it)-1].str(10) << std::endl;
result.push_back(va[(*it)-1]);
}
else
result.push_back(DefaultBigMod()); // NA for out of range's
}
for(unsigned int i = 0 ; i < v_ind.size(); i++){
int indice = v_ind[i];
if(indice < va.size()){
result.push_back(va[indice]);
} else {
result.push_back(bigmod());
}
}
return (result);
}
......@@ -506,55 +466,30 @@ SEXP biginteger_set_at(SEXP src, SEXP idx, SEXP value)
bigvec result = bigintegerR::create_bignum(src);
bigvec vvalue = bigintegerR::create_bignum(value);
vector<int> vidx = bigintegerR::create_int(idx);
vector<bool> vidx = extract_gmp_R::indice_set_at(result.size(),idx);
if(vvalue.size() == 0) {
if(result.size() == 0)
return bigintegerR::create_SEXP(result);
else
else {
int count = 0;
for (int i = 0 ; i < vidx.size(); i++){
if(vidx[i]) count++;
}
if(count >0)
error(_("replacement has length zero"));
}
//case: logicals
if (TYPEOF(idx) == LGLSXP) {
int pos = 0;
for (unsigned int i = 0; i < result.size(); ++i)
if (vidx[i%vidx.size()])
result.set(i, vvalue[pos++ % vvalue.size()]);
return bigintegerR::create_SEXP(result);
}
else {
std::remove(vidx.begin(), vidx.end(), 0); // remove all zeroes
if (vidx.empty())
return bigintegerR::create_SEXP(result);
// return = (src[-idx] <- value)
if (vidx[0] < 0) {
for (vector<int>::iterator it = vidx.begin(); it != vidx.end(); ++it)
if (*it > 0)
error(_("only 0's may mix with negative subscripts"));
else if (-(*it)-1 >= (int)result.size())
error(_("subscript out of bounds"));
int pos = 0;
for (int i = 0; i < (int)result.size(); ++i)
if (find(vidx.begin(), vidx.end(), -i-1) == vidx.end())
result.set(i, vvalue[pos++%vvalue.size()]);
}
//standard case: return = (src[idx] <- value) with idx: positive integer
else {
// finding maximum to resize vector if needed
int maximum = INT_MIN;
for (vector<int>::iterator it = vidx.begin(); it != vidx.end(); ++it)
maximum = max(maximum, *it);
if (maximum > (int)result.size())
result.resize(maximum);
int pos = 0;
for (vector<int>::iterator it = vidx.begin(); it != vidx.end(); ++it) {
if (*it < 0)
error(_("only 0's may mix with negative subscripts"));
result.set((*it)-1,vvalue[pos++%vvalue.size()]);
else
return bigintegerR::create_SEXP(result);
}
}
}
int pos = 0;
for(int i = 0 ; i < result.size(); i++){
if(vidx[i]) result.set(i,vvalue[pos++ % vvalue.size()]);
}
return bigintegerR::create_SEXP(result);
}
SEXP biginteger_length(SEXP a)
......
......@@ -4,7 +4,7 @@
* \version 1
*
* \date Created: 2006
* \date Last modified: Time-stamp: <2010-04-10 19:21:20 antoine>
* \date Last modified: Time-stamp: <2022-02-21 17:07:08 (antoine)>
*
*
* \note Licence: GPL (>= 2)
......@@ -184,6 +184,7 @@ extern "C"
*/
SEXP biginteger_as_integer(SEXP a);
/**
* \brief Return the length of the vector
*/
......
......@@ -24,7 +24,7 @@ using namespace std;
#include "bigrationalR.h"
#include "matrix.h"
#include "extract_matrix.h"
namespace bigrationalR
{
......@@ -428,41 +428,22 @@ SEXP bigrational_as_numeric(SEXP a)
SEXP bigrational_get_at(SEXP a, SEXP b)
{
bigvec_q va = bigrationalR::create_bignum(a);
vector<int> vb = bigintegerR::create_int(b);
vector<int> v_ind = extract_gmp_R::indice_get_at(va.size(),b);
bigvec_q result;
if (TYPEOF(b) == LGLSXP) {
for (unsigned int i = 0; i < va.size(); ++i)
if (vb[i%vb.size()])
result.push_back(va.value[i]);
} else {
std::remove(vb.begin(), vb.end(), 0); // remove all zeroes
if (vb.empty())
return bigrationalR::create_SEXP(bigvec_q());
if (vb[0] < 0) {
for (vector<int>::iterator it = vb.begin(); it != vb.end(); ++it)
if (*it > 0)
error(_("only 0's may mix with negative subscripts"));
else if (-(*it)-1 >= (int)va.size())
error(_("subscript out of bounds"));
// TODO: This is optimized for large va.size and small vb.size.
// Maybe add a condition to use a different approach for large vb's
result.value.reserve(va.size()-vb.size());
for (int i = 0; i < (int)va.size(); ++i)
if (find(vb.begin(), vb.end(), -i-1) == vb.end())
result.push_back(va.value[i]);
for(unsigned int i = 0 ; i < v_ind.size(); i++){
int indice = v_ind[i];
if(indice < va.size()){
result.push_back(va[indice]);
} else {
result.value.reserve(vb.size());
for (vector<int>::iterator it = vb.begin(); it != vb.end(); ++it) {
if (*it < 0)
error(_("only 0's may mix with negative subscripts"));
if (*it <= (int)va.size())
result.push_back(va.value[(*it)-1]);
else
result.push_back(bigrational()); // NA for out of range's
}
result.push_back(bigrational());
}
}
return bigrationalR::create_SEXP(result);
}
......@@ -472,48 +453,29 @@ SEXP bigrational_set_at(SEXP src, SEXP idx, SEXP value)
int i;
bigvec_q result = bigrationalR::create_bignum(src);
bigvec_q vvalue = bigrationalR::create_bignum(value);
vector<int> vidx = bigintegerR::create_int(idx);
vector<bool> vidx = extract_gmp_R::indice_set_at(result.size(),idx);
int pos = 0;
if(vvalue.size() == 0) {
if(result.size() == 0)
return bigrationalR::create_SEXP(result);
else
else{
int count = 0;
for (int i = 0 ; i < vidx.size(); i++){
if(vidx[i]) count++;
}
if(count >0)
error(_("replacement has length zero"));
}
if (TYPEOF(idx) == LGLSXP) {
for (i = 0; i < (int)result.size(); ++i)
if (vidx[i%vidx.size()])
result.value[i] = vvalue.value[pos++%vvalue.size()];
} else {
std::remove(vidx.begin(), vidx.end(), 0); // remove all zeroes
if (vidx.empty())
return bigrationalR::create_SEXP(result);
if (vidx[0] < 0) {
for ( it = vidx.begin(); it != vidx.end(); ++it)
if (*it > 0)
error(_("only 0's may mix with negative subscripts"));
else if (-(*it)-1 >= (int)result.size())
error(_("subscript out of bounds"));
pos = 0;
for ( i = 0; i < (int)result.size(); ++i)
if (find(vidx.begin(), vidx.end(), -i-1) == vidx.end())
result.value[i] = vvalue.value[pos++%vvalue.size()];
} else {
// finding maximum to resize vector if needed
int maximum = INT_MIN;
for (it = vidx.begin(); it != vidx.end(); ++it)
maximum = max(maximum, *it);
if (maximum > (int)result.size())
result.value.resize(maximum);
pos = 0;
for (it = vidx.begin(); it != vidx.end(); ++it) {
if (*it < 0)
error(_("only 0's may mix with negative subscripts"));
result.value[(*it)-1] = vvalue[pos++%vvalue.size()];
else
return bigrationalR::create_SEXP(result);
}
}
}
for(int i = 0 ; i < result.size(); i++){
if(vidx[i]) result.set(i,vvalue[pos++ % vvalue.size()]);
}
return bigrationalR::create_SEXP(result);
}
......
......@@ -104,7 +104,12 @@ std::vector<bool> extract_gmp_R::indice_set_at (unsigned int n , SEXP & IND)
//INTEGERS
{
vidx.erase(std::remove(vidx.begin(), vidx.end(), 0L), vidx.end()); // remove all zeroes
if(vidx.size() == 0){
//for (std::vector<bool>::iterator it = result.begin(); it != result.end(); ++it)
//*it = true;
return result;
}
//negatives integers: all except indices will be modified
if (vidx[0] < 0)
{
......@@ -136,3 +141,66 @@ std::vector<bool> extract_gmp_R::indice_set_at (unsigned int n , SEXP & IND)
}//end of indice_set_at
//
// return a vector of integers corresponding to values that must be affected.
//
std::vector<int> extract_gmp_R::indice_get_at (unsigned int n , SEXP & IND)
{
std::vector<int> vidx = bigintegerR::create_int(IND);
std::vector<int> result;
if(TYPEOF(IND) == NILSXP){
//LOCICAL: return true
for (int i = 0; i< n ; i++){
result.push_back(i);
}
}
else if (TYPEOF(IND) == LGLSXP)
{
// boolean
for(unsigned int i = 0; i< n; ++i)
if (vidx[i % vidx.size() ] ) result.push_back(i);
}
else
//INTEGERS
{
vidx.erase(std::remove(vidx.begin(), vidx.end(), 0L), vidx.end()); // remove all zeroes
if(vidx.size() == 0) return result;
//negatives integers: all except indices will be modified
if (vidx[0] < 0)
{
std::vector<bool> tempo(n,true);
for (std::vector<int>::const_iterator jt = vidx.begin(); jt != vidx.end(); ++jt)
{
if(*jt > 0)
error(_("only 0's may mix with negative subscripts"));
if( (*jt != 0) && (*jt >= - static_cast<int>(n)))
tempo[-(*jt)-1] = false;
}
for (unsigned int i =0 ; i < n ; i++){
if(tempo[i]) result.push_back(i);
}
}
else
{
//INTEGERS (and positive)
for (std::vector<int>::const_iterator jt = vidx.begin(); jt != vidx.end(); ++jt) {
int i = *jt;
if(i < 0)
error(_("only 0's may mix with negative subscripts"));
result.push_back(i-1);
}
}
}
return(result);
}//end of indice_set_at
......@@ -58,6 +58,7 @@ namespace extract_gmp_R
*/
std::vector<bool> indice_set_at (unsigned int n , SEXP & IND);
std::vector<int> indice_get_at (unsigned int n , SEXP & IND);
/**
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment