PDLA
view release on metacpan or search on metacpan
Basic/Core/pdlcore.c.PL view on Meta::CPAN
}
len++; // convert from funky av_len return value to real count
if (av_len(dims) >= level && av_fetch(dims, level, 0) != NULL
&& SvIOK(*(av_fetch(dims, level, 0)))) {
oldlen = (PDLA_Indx) SvIV(*(av_fetch(dims, level, 0)));
if (len > oldlen)
sv_setiv(*(av_fetch(dims, level, 0)), (IV) len);
}
else
av_store(dims,level,newSViv((IV) len));
/* We found at least one element -- so pad dims to unity at levels earlier than this one */
if(n_scalars) {
for(i=0;i<level;i++) {
SV **svp = av_fetch(dims, i, 0);
if(!svp) {
av_store(dims, i, newSViv((IV)1));
} else if( (PDLA_Indx)SvIV(*svp) == 0) {
sv_setiv(*svp, (IV)1);
}
}
for(i=level+1; i <= av_len(dims); i++) {
SV **svp = av_fetch(dims, i, 0);
if(!svp) {
av_store(dims, i, newSViv((IV)1));
} else if( (PDLA_Indx)SvIV(*svp) == 0) {
sv_setiv(*svp, (IV)1);
}
}
}
return depth;
}
/**********************************************************************
* pdl_from_array - dispatcher gets called only by pdl_avref (defined in
* Core.xs) - it breaks out to pdl_setav_<type>, below, based on the
* type of the destination PDLA.
*/
pdl* pdl_from_array(AV* av, AV* dims, int type, pdl* p)
{
int ndims, i, level=0;
PDLA_Indx *pdims;
PDLA_Anyval undefval;
ndims = av_len(dims)+1;
pdims = (PDLA_Indx *) pdl_malloc( (ndims) * sizeof(*pdims) );
for (i=0; i<ndims; i++) {
pdims[i] = SvIV(*(av_fetch(dims, ndims-1-i, 0))); /* reverse order */
}
if (p == NULL)
p = pdl_new();
pdl_setdims (p, pdims, ndims);
p->datatype = type;
pdl_allocdata (p);
pdl_make_physical(p);
/* this one assigns the data */
{
/******
* Copy the undefval to fill empty spots in the piddle...
*/
SV *sv = get_sv("PDLA::undefval",0);
undefval = ((!sv) || (sv==&PL_sv_undef)) ? 0 : (PDLA_Anyval)SvNV(sv);
}
switch (type) {
!NO!SUBS!
##########
# Perl snippet autogenerates switch statement to distribute
# pdl_setav calls...
#
for my $type(sort keys %PDLA_DATATYPES){
my $t2 = $PDLA_DATATYPES{$type};
$t2 =~ s/PDLA_//;
print OUT <<"!WITH!SUBS!";
case $type:
pdl_setav_$t2(p->data,av,pdims,ndims,level, undefval);
break;
!WITH!SUBS!
}
#
# Back to your regularly scheduled C code emission...
########
print OUT <<'!NO!SUBS!';
default:
croak("pdl_from_array: internal error: got type %d",type);
break;
}
p->state &= ~PDLA_NOMYDIMS;
return p;
}
/*
* pdl_kludge_copy_<type> - copy a PDLA into a part of a being-formed PDLA.
* It is only used by pdl_setav_<type>, to handle the case where a PDLA is part
* of the argument list.
*
* kludge_copy recursively walks down the dim list of both the source and dest
* pdls, copying values in as we go. It differs from PP copy in that it operates
* on only a portion of the output pdl.
*
* (If I were Lazier I would have popped up into the perl level and used threadloops to
* assign to a slice of the output pdl -- but this is probably a little faster.)
*
* -CED 17-Jun-2004
*
* Arguments:
* poff is an integer indicating which element along the current direction is being treated (for padding accounting)
* pdata is a pointer into the destination PDLA's data;
* pdims is a pointer to the destination PDLA's dim list;
* ndims is the size of the destination PDLA's dimlist;
( run in 0.650 second using v1.01-cache-2.11-cpan-39bf76dae61 )