Revision 67ef2752d7a4a3f782d23ea6a4ac07892ed0624d authored by Ronny Lorenz on 02 June 2023, 13:59:43 UTC, committed by Ronny Lorenz on 09 June 2023, 18:49:56 UTC
1 parent 8575951
var_arrays.i
/**********************************************/
/* BEGIN interface variable length arrays */
/**********************************************/
%{
#include <sstream>
#define VAR_ARRAY_LINEAR 1U
#define VAR_ARRAY_TRI 2U
#define VAR_ARRAY_SQR 4U
#define VAR_ARRAY_ONE_BASED 8U
#define VAR_ARRAY_OWNED 16U
template <typename T>
struct var_array {
size_t length;
T *data;
unsigned int type;
};
template <typename T>
std::string
var_array_type_str(var_array<T> *a)
{
std::ostringstream out;
if (a->type & VAR_ARRAY_LINEAR)
out << "RNA.VAR_ARRAY_LINEAR";
else if (a->type & VAR_ARRAY_TRI)
out << "RNA.VAR_ARRAY_TRI";
else if (a->type & VAR_ARRAY_SQR)
out << "RNA.VAR_ARRAY_SQR";
if (a->type & VAR_ARRAY_ONE_BASED)
out << " | RNA.VAR_ARRAY_ONE_BASED";
return std::string(out.str());
}
/* determine length n given array_size elements of the respective
upper triangular square matrix. Here, we assume that the largest
entry in the array resides at position (n*(n-1))/2 + n. So the
actual size of the array is (n*(n-1))/2 + n + 1, since arrays
are always 0-based
*/
inline size_t
var_array_tri_size(size_t array_size)
{
return (size_t)floor((sqrt(8 * array_size - 7) - 1) / 2);
}
/* compute number of entries in the upper-triangular n*n square
matrix with dimension n
*/
inline size_t
var_array_data_size_tri(size_t n)
{
return (n * (n - 1)) / 2 + n + 1;
}
/* determine length n given array_size elements of the respective
square matrix
*/
inline size_t
var_array_sqr_size(size_t array_size)
{
return (size_t)(sqrt(array_size - 1));
}
/* compute number of entries in the n*n square
matrix with dimension n
*/
inline size_t
var_array_data_size_sqr(size_t n)
{
return n * n + 1;
}
/****************/
/* Constructors */
/****************/
template <typename T>
inline var_array<T> *
var_array_new(size_t length,
T *data,
unsigned int type)
{
var_array<T> *a = NULL;
if ((length) &&
(data)) {
a = (var_array<T> *)vrna_alloc(sizeof(var_array<T>));
a->length = length;
a->data = data;
a->type = type;
}
return a;
}
%}
%nodefaultctor var_array;
%nodefaultdtor var_array;
template <typename T>
struct var_array {};
/***************************************/
/* Constructor/Destructor */
/***************************************/
%extend var_array {
var_array(std::vector<T> d,
unsigned int type) {
var_array<T> *a = NULL;
size_t n = d.size();
if (n > 0) {
a = (var_array<T> *)vrna_alloc(sizeof(var_array<T>));
a->data = (T *)vrna_alloc(sizeof(T) * n);
memcpy(a->data, &(d[0]), sizeof(T) * n);
if (type & VAR_ARRAY_TRI)
n = var_array_tri_size(n);
else if (type & VAR_ARRAY_SQR)
n = var_array_sqr_size(n);
else if ((type & VAR_ARRAY_LINEAR) &&
(type & VAR_ARRAY_ONE_BASED))
n -= 1;
a->length = n;
a->type = type | VAR_ARRAY_OWNED;
}
return a;
}
~var_array() {
if ($self->type & VAR_ARRAY_OWNED)
free($self->data);
free($self);
}
};
%extend var_array<short> {
var_array(std::vector<int> data,
unsigned int type = VAR_ARRAY_LINEAR | VAR_ARRAY_ONE_BASED) {
var_array<short> *a = NULL;
size_t n = data.size();
if (n > 0) {
short *data_s = (short *)vrna_alloc(sizeof(short) * n);
for (size_t i = 0; i < n; i++)
data_s[i] = (short)data[i];
if (type & VAR_ARRAY_TRI)
n = var_array_tri_size(n);
else if (type & VAR_ARRAY_SQR)
n = var_array_sqr_size(n);
else if ((type & VAR_ARRAY_LINEAR) &&
(type & VAR_ARRAY_ONE_BASED))
n -= 1;
a = var_array_new(n, data_s, type | VAR_ARRAY_OWNED);
}
return a;
}
};
/***************************************/
/* Extensions for [] operator access */
/***************************************/
%extend var_array {
size_t __len__() const {
size_t n = $self->length;
if ($self->type & VAR_ARRAY_ONE_BASED)
n += 1;
if ($self->type & VAR_ARRAY_TRI)
n = var_array_data_size_tri(n - 1);
else if ($self->type & VAR_ARRAY_SQR)
n = var_array_data_size_sqr(n);
return n;
}
const T __getitem__(int i) const throw(std::out_of_range) {
size_t max_i = $self->length;
if ($self->type & VAR_ARRAY_ONE_BASED)
max_i += 1;
if ($self->type & VAR_ARRAY_TRI)
max_i = var_array_data_size_tri(max_i - 1);
else if ($self->type & VAR_ARRAY_SQR)
max_i = var_array_data_size_sqr(max_i);
if ((i < 0) ||
(i >= max_i))
throw std::out_of_range("out of bounds access");
return $self->data[i];
}
const T __setitem__(int i, const T d) const throw(std::out_of_range) {
size_t max_i = $self->length;
if ($self->type & VAR_ARRAY_ONE_BASED)
max_i += 1;
if ($self->type & VAR_ARRAY_TRI)
max_i = var_array_data_size_tri(max_i - 1);
else if ($self->type & VAR_ARRAY_SQR)
max_i = var_array_data_size_sqr(max_i);
if ((i < 0) ||
(i >= max_i))
throw std::out_of_range("out of bounds access");
return $self->data[i] = d;
}
};
#ifdef SWIGPYTHON
%extend var_array {
std::string
__str__()
{
size_t n = $self->length;
if ($self->type & VAR_ARRAY_ONE_BASED)
n += 1;
if ($self->type & VAR_ARRAY_TRI)
n = var_array_data_size_tri(n - 1);
else if ($self->type & VAR_ARRAY_SQR)
n = var_array_data_size_tri(n);
std::ostringstream out;
out << "{ data: [" << $self->data[0];
for (size_t i = 1; i < n; i++)
out << ", " << $self->data[i];
out << "], ";
out << "type: " << var_array_type_str($self);
out << " }";
return std::string(out.str());
}
%pythoncode %{
def __repr__(self):
# reformat string representation (self.__str__()) to something
# that looks like a constructor argument list
strthis = self.__str__().replace(": ", "=").replace("{ ", "").replace(" }", "")
return "%s.%s(%s)" % (self.__class__.__module__, self.__class__.__name__, strthis)
%}
};
#endif
%template (varArrayUChar) var_array<unsigned char>;
%template (varArrayChar) var_array<char>;
%template (varArrayShort) var_array<short>;
%template (varArrayUInt) var_array<unsigned int>;
%template (varArrayInt) var_array<int>;
%template (varArrayFLTorDBL) var_array<FLT_OR_DBL>;
%constant unsigned int VAR_ARRAY_LINEAR = VAR_ARRAY_LINEAR;
%constant unsigned int VAR_ARRAY_TRI = VAR_ARRAY_TRI;
%constant unsigned int VAR_ARRAY_SQR = VAR_ARRAY_SQR;
%constant unsigned int VAR_ARRAY_ONE_BASED = VAR_ARRAY_ONE_BASED;
%constant unsigned int VAR_ARRAY_OWNED = VAR_ARRAY_OWNED;
Computing file changes ...