PDL
view release on metacpan or search on metacpan
lib/PDL/Core.pm view on Meta::CPAN
my ($item, $sofar) = @_;
barf("Error: $sofar > max type value($MAX_TYPE)") if $sofar > $MAX_TYPE;
return $sofar if $sofar == $MAX_TYPE;
return $PDL_CD if UNIVERSAL::isa($item, 'Math::Complex');
return max($item->type->enum, $sofar) if UNIVERSAL::isa($item, 'PDL');
return $PDL_D if ref($item) ne 'ARRAY';
# only need to check first item for an array of complex vals
return $MAX_TYPE if _establish_type($item->[0], $sofar) == $MAX_TYPE;
# only need to recurse for items that are refs
# as $sofar will be $PDL_D at a minimum
max ($sofar, map _establish_type($_, $sofar), grep ref, @$item);
}
sub PDL::new {
return $_[0]->copy if ref($_[0]) and UNIVERSAL::isa($_[0], 'PDL');
my $this = shift;
my $type = ref($_[0]) eq 'PDL::Type' ? shift->enum : undef;
my $value = (@_ > 1 ? [@_] : shift);
unless(defined $value) {
if($PDL::debug) {
print STDERR "Warning: PDL::new converted undef to \$PDL::undefval ($PDL::undefval)\n";
}
$value = ($PDL::undefval//0)+0
}
$type //= ref($value) ? _establish_type($value, $PDL_D) : $PDL_D;
return pdl_avref($value,$this,$type) if ref($value) eq "ARRAY";
my $new = $this->initialize;
$new->set_datatype($type);
if (ref(\$value) eq "SCALAR") {
# The string processing is extremely slow. Benchmarks indicated that it
# takes 10x longer to process a scalar number compared with normal Perl
# conversion of a string to a number. So, only use the string processing
# if the input looks like a real string, i.e. it doesn't look like a plain
# number. Note that for our purposes, looks_like_number incorrectly
# handles the strings 'inf' and 'nan' on Windows machines. We want to send
# those to the string processing, so this checks for them in a way that
# short-circuits the looks_like_number check.
if (PDL::Core::is_scalar_SvPOK($value)
and ($value =~ /inf/i or $value =~ /nan/i
or !Scalar::Util::looks_like_number($value))) {
# new was passed a string argument that doesn't look like a number
# so we can process as a Matlab-style data entry format.
return PDL::Core::new_pdl_from_string($new,$value,$this,$type);
} elsif (! $CAN_PACK_QUAD && $pack[$new->get_datatype] =~ /^q\*$/i ) {
# special case when running on a perl without 64bit int support
# we have to avoid pack("q", ...) in this case
# because it dies with error: "Invalid type 'q' in pack"
$new->setdims([]);
set_c($new, [0], $value);
} elsif (! $CAN_PACK_D && $pack[$new->get_datatype] =~ /^(\QD*\E|\Q(DD)*\E)$/ ) {
# if "D" is not available for pack(),
# it dies with error: "Invalid type 'D' in pack".
$new->setdims([]);
set_c($new, [0], $value);
} else {
$new->setdims([]);
if ($value) {
$new->update_data_from( pack $pack[$new->get_datatype], $value );
} else { # do nothing if 0 - allocdata already memsets to 0
$new->make_physical;
}
}
}
elsif (blessed($value) and UNIVERSAL::isa($value, 'Math::Complex')) {
$new->setdims([]);
set_c($new, [], $value);
}
elsif (blessed($value)) { # Object
$new = $value->copy;
}
else {
barf("Can not interpret argument $value of type ".ref($value) );
}
$new;
}
=head2 copy
=for ref
Make a physical copy of an ndarray
=for usage
$new = $old->copy;
Since C<$new = $old> just makes a new reference, the
C<copy> method is provided to allow real independent
copies to be made.
=cut
sub PDL::copy {
my $value = shift;
barf("Argument is an ".ref($value)." not an object") unless blessed($value);
return $value->nullcreate if $value->isnull;
# broadcastI(-1,[]) is just an identity vafftrans with broadcastid copying ;)
my $is_inplace = $value->is_inplace;
$value->set_inplace(0) if $is_inplace;
my $ret = $value->broadcastI(-1,[])->sever;
$value->set_inplace(1) if $is_inplace;
$ret;
}
=head2 hdr_copy
=for ref
Return an explicit copy of the header of a PDL.
hdr_copy is just a wrapper for the internal routine _hdr_copy, which
takes the hash ref itself. That is the routine which is used to make
copies of the header during normal operations if the hdrcpy() flag of
a PDL is set.
General-purpose deep copies are expensive in perl, so some simple
optimization happens:
( run in 1.793 second using v1.01-cache-2.11-cpan-39bf76dae61 )