http://www.perlmonks.org?node_id=1066026

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

Hello all, I am a bit confused with the approach to nesting arrays. What my program does: randomly select a string with four elements from a data frame with 1553 strings, 1553 times and store the new order of these strings within an array or data frame. Then I would like to repeat this 1,000 times.

I have written this to output each rearranged assembly of 1553 strings into a separate output file because I do not understand how to store a matrix within a matrix. Could someone help explain the concept behind this idea?

# Inputs my $runs = 100000; # 1e5 - the num of times we repeat the exper +iment # Program vars my $i; # a looping variable my $j; # another looping var my $range = 1553; # the number of total window +s with data my $count = 0; # variable tracking pseudo X output + files # Outer loop: Repeat "$runs" times for ($j = 0; $j < $runs; $j++) { for ($i = 0; $i < $range + 1 ; $i++) { # choose a randomly selected string chomp @X_info; my @get_X = split('\s+', $X_info[int(rand($range))]); my $output_file = "/Users/statistical_analysis/pseudo_X/pseuo_ +X_"."$count".".txt"; open (OUT, ">$output_file") or die "can't open output file"; print OUT "@get_X\n"; } } $count++;

Replies are listed 'Best First'.
Re: A Question with Nesting Arrays
by Kenosis (Priest) on Dec 06, 2013 at 19:02 UTC

    ...I am a bit confused...

    Me too, but I may not have had enough coffee, yet.

    I don't see that your program's strictly doing what you want it to do, i.e., forming a new order of these strings, since you could be randomly selecting the same element from @X_info multiple times, creating a new set of strings (but perhaps that's what you do want).

    However, if your goal is to randomly shuffle the array of strings n times, while maintaining that set of strings, then consider the following:

    use warnings; use strict; use List::Util qw/shuffle/; my $runs = 1000; my $range = 1553; my @array = ( 'A' .. 'Z' ); @array = shuffle @array for 1 .. $runs * $range; print "@array";

    Output:

    E I C M P Y D B F Q U J X R V T Z H S N G A O W K L

    Hope this helps!

Re: A Question with Nesting Arrays
by toolic (Bishop) on Dec 06, 2013 at 18:25 UTC
    my $runs = 100000; # 10 thousand - the num of times we repeat the experiment
    That's a confusing comment. 100000 can be written as 100_000 (see Scalar value constructors):
    my $runs = 100_000;

      That's a confusing comment.

      indeed! And it is still confusing. Maybe write my $runs = 10 * 1000; #to be on the safe side.

      Cheers, Sören

      Créateur des bugs mobiles - let loose once, run everywhere.
      (hooked on the Perl Programming language)

        Afraid of scientific notation? $runs = 1e5;

      I'd have thought"
      "my $runs = 100000;"
      meant 100 thousand. Not the
      "10 thousand",
      noted by the OP.

      In any event. It'd be interesting to see the solution to the OP's question. :)

      Hey. I'm not completely useless. I can be used as a bad example.
      
Re: A Question with Nesting Arrays
by BrowserUk (Patriarch) on Dec 06, 2013 at 23:39 UTC

    How to quickly produce 100,000 of, the 2.658e+4283 combinations of, 1,553 values:

    use List::Util qw[ shuffle ]; my @data = 1 .. 1553;; my @results = map[ shuffle @data ], 1.. 1e5;

    Done.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: A Question with Nesting Arrays
by ww (Archbishop) on Dec 06, 2013 at 22:47 UTC

    I'm quite sure that I don't understand your reference to "randomly select a string with four elements from a data frame with 1553 strings..." -- so, as in Kenosis reply above, I've worked with a string comprised of "A" .. "Z" and taken a couple additional steps to obtain the one-thousandth permutation *1 (shuffle) thereof:

    #!/usr/bin/perl use 5.016; use warnings; use List::Util qw/shuffle/; my $runs = 10^3; my $range = 1553; my @letterRange = ( 'A' .. 'Z' ); my $i = 0; my (@array, @arr2, $key, $valref, $permutes); my %permutes = (); for ($i=1;$i<=$range;$i++) { # C-style, start w/"1"; "0" would g +ive 1554 elements @array = shuffle @letterRange for 1 ..$runs; # @arr will hold th +e 1000th shuffle $key = "@array"; $permutes {$key } = $i; } for my $key ( keys %permutes ) { my $value = $permutes{$key}; push @arr2, "$value => $key"; } print "size of hash: " . keys( %permutes ) . ".\n"; no warnings 'numeric'; my @sorted = sort {$a <=> $b} @arr2; use warnings; for $_ (@sorted) { say $_; }

    The output looks like this:

    size of hash: 1553. 1 => V Y N H D R W Q C B E F T L S I J M O U Z A G X P K 2 => W E C B M V P I Y U D K G A T Z R O N F S J L X Q H 3 => L A T Y N R C Z J O V U G Q H F B S K W I E X P M D ...

    ... no dupes, no missing iteration numbers found but a selection of the output is in the readmore which follows:

    *1: Reiterating, I doubt this is the solution to your problem -- as noted above, I simply don't understand a part of your problem statement (and the code doesn't illuminate the meaning for /me) but I do hope this may offer an approach to your specific case.

Re: A Question with Nesting Arrays
by jethro (Monsignor) on Dec 06, 2013 at 21:20 UTC

    At the moment you store everything into only one file because the increment of $count happens outside both loops. We might better understand your problem if you showed us the input and the expected output of a smaller problem, with 5 instead of 1553 strings and only 3 runs for example

    Should you be looking for information about matrices, in perl they are called Arrays of Arrays or AoAs, Dense but concise information about them can be found for example in perllol and perldsc

Re: A Question with Nesting Arrays
by marinersk (Priest) on Dec 06, 2013 at 22:43 UTC
    You can use arrays of arrays of course, but if your dimensions are fixed, known, and consistent, why not just use two- or three- dimensional arrays and be done with it?
    my @array = (); my $index_x = 0; my $index_y = 0; my $index_z = 0; {...} $arrays[$index_x][$index_y][$index_z] = 52;
      You hopefully are aware that your three dimensional array (at least in perl) is still an array of arrays. It sounds like you think of them as something different.

        Yes, internally. But it has been my experience that newcomers to the language can wrap their heads around the multidimensional syntax more quickly than diving straight into indirect references.

        And this is my third attempt to post this answer; for some reason, PerlMonks doesn't seem to want me to say this. If it fails a third time, I will surrender. :-)