kesterkester has asked for the wisdom of the Perl Monks concerning the following question:

Hi All--

It's clearly friday afternoon-- I can't figure out how to do a trivial set intersection in PDL.

I have:

use PDL; my $pdl_a = pdl 10..20; my $pdl_b = pdl 15..18; print "$pdl_a\n$pdl_b\n";

Producing this:

[10 11 12 13 14 15 16 17 18 19 20] [15 16 17 18]

I want:

use PDL; my $pdl_a = pdl 10..20; my $pdl_b = pdl 15..18; my $pdl_c = INTERSECTION OF PDL_A AND PDL_B print "$pdl_a\n$pdl_b\n$pdl_c\n";

Producing this:

[10 11 12 13 14 15 16 17 18 19 20] [15 16 17 18] [15 16 17 18]

What am I forgetting, O Monks?

Replies are listed 'Best First'.
Re: Simple PDL question: set intersection
by kvale (Monsignor) on Oct 29, 2004 at 23:34 UTC
    I don't know of a direct set intersection operator on the values of a pdl. For your example, you can use conditionals to effect the same result:
    use PDL; my $arr = pdl 10..20;; print $arr, "\n"; my $idx = which( $arr>14 & $arr<19 ); print $idx, "\n"; my $subset = $arr->index( $idx); print $subset, "\n";
    prints
    [10 11 12 13 14 15 16 17 18 19 20] [5 6 7 8] [15 16 17 18]
    If you need real set intersection and not just subranges, converting to hashes may be the easiest apporach.

    -Mark

Re: Simple PDL question: set intersection
by etj (Priest) on Jun 22, 2022 at 20:10 UTC
Re: Simple PDL question: set intersection
by tall_man (Parson) on Nov 01, 2004 at 16:11 UTC
    If the sets contain integers in a reasonable range you could use indexing, like this:
    use strict; use PDL; my $pdl_a = pdl 10..20; my $pdl_b = pdl 15..18; my $mask_a = zeroes 21; my $mask_b = zeroes 21; my $set_a = index($mask_a, $pdl_a); my $set_b = index($mask_b, $pdl_b); $set_a .= 1; $set_b .= 1; my $pdl_c = which($mask_a & $mask_b); print $pdl_c,"\n";
    If the sets are large you could use bit masking, as in this example: Re^2: Basic Perl trumps DBI? Or my poor DB design?.