Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there a consistent way to use a PDL to index an @array? #400

Closed
KJ7LNW opened this issue Jun 17, 2022 · 7 comments
Closed

Is there a consistent way to use a PDL to index an @array? #400

KJ7LNW opened this issue Jun 17, 2022 · 7 comments
Labels

Comments

@KJ7LNW
Copy link

KJ7LNW commented Jun 17, 2022

I realize this isn't a bug report, so if you prefer this type of question on a mailing list or somewhere else please direct me to the right place:

I've run into what is (for me) a confusing issue using PDL's to index perl arrays. Maybe that should always be avoided?

Here is what I've found:

pdl> @a = (3,4,5)
pdl> p $a[2]
5
pdl> p $a[pdl 2]
5
pdl> p $a[pdl [2]]
3

pdl> p int(pdl 2)
2
pdl> p int(pdl [2])
0
pdl> help pdl 2
This variable is Double D []                   P            0.01KB

pdl> help pdl [2]
This variable is Double D [1]                  P            0.01KB

pdl> help pdl [[2]]
This variable is Double D [1,1]                P            0.01KB

Then looking at the resulting structure from unpdl, these are the same structure:

pdl> use Data::Dumper
pdl> p Dumper unpdl(pdl 2)
$VAR1 = [
          '2'
        ];

pdl> p Dumper unpdl(pdl [2])
$VAR1 = [
          '2'
        ];

Same structure, but pdl 2 can be used as an array index and pdl [2] cannot because int(pdl[2])==0.

  • When can a piddle be used to index a Perl array?
  • Is there a way to unwrap 1D and 0D and [1,1]-D variables into a scalar that will not show up as 0 at unexpected times?
@KJ7LNW KJ7LNW changed the title Is there a consistent way to use a PDL to index an array? Is there a consistent way to use a PDL to index an @array? Jun 17, 2022
@mohawk2
Copy link
Member

mohawk2 commented Jun 17, 2022

pdl($single_value) returns a PDL scalar (a dimensionless ndarray, so one value). pdl([$single_value]) makes an ndarray with a single dimension of size 1. Arguably this is a bug in unpdl since the round-trip does not end up with a similarly-shaped Perl value. I will note that unpdl has existed for quite a few years and this is the first time that's been considered a problem.

I'm afraid I don't understand what you mean when you say int(pdl[2])==0. int is a Perl function, and is likely to interact badly with ndarrays; if you mean to convert the ndarray to indx (which isn't really necessary), use that: indx(pdl([2])).

Please show some code that demonstrates the problem you are having with indexing; indexing an ndarray with either index, indexND, dice, dice_axis, slice, or range all work great with ndarrays as index inputs.

@KJ7LNW
Copy link
Author

KJ7LNW commented Jun 18, 2022

I wanted to use a $pdl as an index to a perl array, so Perl needs to see the evaluation as an int.

For example:

@a = (1,2,3);
$p = pdl [2];
print $a[$p]

The print should show "3" but it shows "1" because int(pdl [2]) == 0. I tried $a[indx $p] but it still prints "1" instead of "3".

How do you go back and forth (reliably) between a perl int and a pdl int?

@zmughal
Copy link
Member

zmughal commented Jun 18, 2022

@KJ7LNW, if what you have is a single-element ndarray, you can use sclr which should do what you want:

use feature qw(say);
use PDL;
say pdl(2)->sclr;      # 2
say pdl([2])->sclr;    # 2
say pdl([[2]])->sclr;  # 2

Though I'm wondering why not also convert the Perl array to a PDL ndarray? I suppose if you only want a single index, it makes sense.

@KJ7LNW
Copy link
Author

KJ7LNW commented Jun 18, 2022

@zmughal, I think sclr is the way to go! Thanks for pointing that out.

In this case @a contains a recursive array of Perl hashes and array structures representing variable names and settings for a set of simplex results, so I'm guessing an array of hashes would not be a valid PDL structure.

The PDL::Opt::Simplex::Simple module blurs the line between PDL and Perl data types in a few places to do what it does. I'm sure in some places that is just because I'm new to PDL, but I think I need ->sclr in at least in the array of data structures case.

Maybe https://metacpan.org/pod/PDL::Core#unpdl should have a note to the effect of "see also $pdl->sclr" because "sclr is generally used when a Perl scalar is required instead of a one-element ndarray."

@zmughal, ->sclr says "As of 2.064, if the input is a multielement ndarray it will throw an exception." so would your example of say pdl([[2]])->sclr; # 2 have failed in 2.064?

@zmughal
Copy link
Member

zmughal commented Jun 18, 2022

In this case @a contains a recursive array of Perl hashes and array structures representing variable names and settings for a set of simplex results, so I'm guessing an array of hashes would not be a valid PDL structure.

Ah, yes, for indexing those data-structures, that makes sense.


->sclr says "As of 2.064, if the input is a multielement ndarray it will throw an exception." so would your example of say pdl([[2]])->sclr; # 2 have failed in 2.064?

What that means is that if an ndarray contains more than one element, it
throws an exception:

# with 2.060
$ use feature qw(say); use PDL; say join " | ", $PDL::VERSION, pdl([[2]])->sclr, do { eval { pdl([3, 4])->sclr } or $@ }
2.060 | 2 | 3
# with 2.079
$ use feature qw(say); use PDL; say join " | ", $PDL::VERSION, pdl([[2]])->sclr, do { eval { pdl([3, 4])->sclr } or $@ }
2.079 | 2 | multielement ndarray in 'sclr' call at .../PDL/Core.pm line 3071.

For the above example ndarrays, all have a single element, but differ in the number of dimensions:

use feature qw(say);
use PDL;
my @pdls = ( pdl(2), pdl([2]), pdl([[2]]) );
say join "\n====\n", map {
	$_->string . "\n" . join ' | ',  $_->nelem, $_->ndims
} @pdls;
# 2
# 1 | 0
# ====
# [2]
# 1 | 1
# ====
#
# [
#  [2]
# ]
#
# 1 | 2

@zmughal
Copy link
Member

zmughal commented Jun 18, 2022

if you prefer this type of question on a mailing list or somewhere else please direct me to the right place:

There are mailing lists and IRC. More info at: https://pdl.perl.org/?page=mailing-lists.

But we appreciate input here on the issue tracker as well!

@KJ7LNW
Copy link
Author

KJ7LNW commented Jun 18, 2022

Thanks @zmughal! I think that answers my questions. Much appreciated.

@KJ7LNW KJ7LNW closed this as completed Jun 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants