Discussion:
[Pdl-porters] Copying piddles into piddles of a different size without wasting memory
Diab Jerius
2015-01-06 17:41:04 UTC
Permalink
I've run into a situation where I need to copy a piddle into an
existing piddle with different dimensions. (Yes, I unfortunately
really need to do this.)

If the dimensions were the same, then the .= (assgn function) would
suffice, but in this case it won't.

The approach I've found is to do something like this:

$pdl1->setdims( [ $pdl2->dims ] );
${ $pdl1->get_dataref} = ${ $pdl2->get_dataref };
$pdl1->upd_data;

The drawback is that $pdl1's storage isn't shrunk if $pdl2 is smaller
than $pdl1 (underneath, Perl's SvGROW() routine is called, and it
won't shrink an SV). What I'd like to do looks schematically like
this:

$pdl1 .= null();
$pdl1 .= $pdl2;

Is there a way of null'ing an existing piddle at the Perl level?

Thanks,
Diab
Craig DeForest
2015-01-06 18:06:58 UTC
Permalink
I don't think there is a Perl-side solution already implemented. On the C/XS/PP side, it's pretty easy, since the "datasv" field of the pdl struct points directly to the SV, and the "data" field of the same pdl struct points to the SV's data area. I could see implementing a new utility ("PDL::new_datasv") to drop a new SV into the PDL:
$pdl1->setdims([ $pdl2->dims ]);
$pdl1->new_datasv( ${$pdl2->get_dataref} ); # creates a new SV in pdl1 and copies the contents of the passed-in SV to it
$pdl1->upd_data; # shouldn't be necessary -- new_datasv should probably just do that automagically

If you need a solution now, your best bet is probably to implement new_datasv either with inline XS or with XS as part of a module.
Post by Diab Jerius
I've run into a situation where I need to copy a piddle into an
existing piddle with different dimensions. (Yes, I unfortunately
really need to do this.)
If the dimensions were the same, then the .= (assgn function) would
suffice, but in this case it won't.
$pdl1->setdims( [ $pdl2->dims ] );
${ $pdl1->get_dataref} = ${ $pdl2->get_dataref };
$pdl1->upd_data;
The drawback is that $pdl1's storage isn't shrunk if $pdl2 is smaller
than $pdl1 (underneath, Perl's SvGROW() routine is called, and it
won't shrink an SV). What I'd like to do looks schematically like
$pdl1 .= null();
$pdl1 .= $pdl2;
Is there a way of null'ing an existing piddle at the Perl level?
Thanks,
Diab
_______________________________________________
PDL-porters mailing list
http://mailman.jach.hawaii.edu/mailman/listinfo/pdl-porters
Karl Glazebrook
2015-01-07 00:10:58 UTC
Permalink
reshape()?

I vaguely remember writing it but might be hallucinating :-)

Karl
Post by Diab Jerius
I've run into a situation where I need to copy a piddle into an
existing piddle with different dimensions. (Yes, I unfortunately
really need to do this.)
If the dimensions were the same, then the .= (assgn function) would
suffice, but in this case it won't.
$pdl1->setdims( [ $pdl2->dims ] );
${ $pdl1->get_dataref} = ${ $pdl2->get_dataref };
$pdl1->upd_data;
The drawback is that $pdl1's storage isn't shrunk if $pdl2 is smaller
than $pdl1 (underneath, Perl's SvGROW() routine is called, and it
won't shrink an SV). What I'd like to do looks schematically like
$pdl1 .= null();
$pdl1 .= $pdl2;
Is there a way of null'ing an existing piddle at the Perl level?
Thanks,
Diab
_______________________________________________
PDL-porters mailing list
http://mailman.jach.hawaii.edu/mailman/listinfo/pdl-porters
Loading...