Algorithm-Cluster
view release on metacpan or search on metacpan
perl/Cluster.xs view on Meta::CPAN
dSP;
I32 count;
bool isEnabled;
SV * mysv;
ENTER ;
SAVETMPS;
PUSHMARK(SP) ;
XPUSHs(sv_2mortal(newSVpv("Algorithm::Cluster",18)));
PUTBACK ;
count = perl_call_pv("warnings::enabled", G_SCALAR) ;
if (count != 1) croak("No arguments returned from call_pv()\n") ;
mysv = POPs;
isEnabled = (bool) SvTRUE(mysv);
PUTBACK ;
FREETMPS ;
LEAVE ;
return isEnabled;
}
/* -------------------------------------------------
* Create a row of doubles, initialized to a value
*/
static double*
malloc_row_dbl(pTHX_ int ncols, double val) {
int j;
double * row;
row = malloc(ncols * sizeof(double) );
if (!row) {
return NULL;
}
for (j = 0; j < ncols; j++) {
row[j] = val;
}
return row;
}
/* -------------------------------------------------
* Only coerce to a double if we already know it's
* an integer or double, or a string which is actually numeric.
* Don't blindly run the macro SvNV, because that will coerce
* a non-numeric string to be a double of value 0.0,
* and we do not want that to happen, because if we test it again,
* it will then appear to be a valid double value.
*/
static int
extract_double_from_scalar(pTHX_ SV * mysv, double * number) {
if (SvPOKp(mysv) && SvLEN(mysv)) {
/* This function is not in the public perl API */
if (Perl_looks_like_number(aTHX_ mysv)) {
*number = SvNV( mysv );
return 1;
} else {
return 0;
}
} else if (SvNIOK(mysv)) {
*number = SvNV( mysv );
return 1;
} else {
return 0;
}
}
/* -------------------------------------------------
* Convert a Perl 2D matrix into a 2D matrix of C doubles.
* If no data are masked, mask can be passed as NULL.
* NOTE: on errors this function returns a value greater than zero.
*/
static double**
parse_data(pTHX_ SV * matrix_ref, int** mask) {
AV * matrix_av;
SV * row_ref;
AV * row_av;
SV * cell;
int type, i, j, nrows, ncols, n;
double** matrix;
/* NOTE -- we will just assume that matrix_ref points to an arrayref,
* and that the first item in the array is itself an arrayref.
* The calling perl functions must check this before we get this pointer.
* (It's easier to implement these checks in Perl rather than C.)
* The value of perl_rows is now fixed. But the value of
* rows will be decremented, if we skip any (invalid) Perl rows.
*/
matrix_av = (AV *) SvRV(matrix_ref);
nrows = (int) av_len(matrix_av) + 1;
if(nrows <= 0) {
return NULL;
}
matrix = malloc(nrows*sizeof(double*));
if (!matrix) {
return NULL;
}
row_ref = *(av_fetch(matrix_av, (I32) 0, 0));
row_av = (AV *) SvRV(row_ref);
ncols = (int) av_len(row_av) + 1;
/* ------------------------------------------------------------
* Loop once for each row in the Perl matrix, and convert it to
* C doubles.
*/
for (i=0; i < nrows; i++) {
( run in 0.900 second using v1.01-cache-2.11-cpan-39bf76dae61 )