Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Re: Write code diferently

by BrowserUk (Pope)
on Aug 23, 2013 at 17:31 UTC ( #1050700=note: print w/ replies, xml ) Need Help??


in reply to Write code diferently

Depending why you want this, there are several different was of doing it; but since you've chosen not to answer the question; here's just one.

while( abs( $mutRate - 0.01) > 1e-16 ) { ++$iter; $k *= $mutRate * 100; # map $_ /= ( $mutRate * 100), @$_ for @lnPAM; for my $aref ( @lnPAM ) { $_ /= ( $mutRate * 100 ) for @$aref; } # @matrix = map[ map exp( $_ ), @$_ ], @lnPAM; undef @matrix; for my $aref ( @lnPAM ) { my @temp; push @temp, exp( $_ ) for @$aref; push @matrix, \@temp; } # $mutRate = sum map{ $freq[ $_ ] * ( 1 - $matrix[ $_ ][ $_ ] ) } +0..19; $mutRate = 0; for my $i ( 0 .. 19 ) { $mutRate += $freq[ $i ] * ( 1 - $matrix[ $i ][ $i ] ); } printf "After %d iteration(s), k=%13.9f, RateMutation=%19.17f\n", +$iter, $k, $mutRate; }

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.


Comment on Re: Write code diferently
Download Code
Re^2: Write code diferently
by Laurent_R (Parson) on Aug 23, 2013 at 19:04 UTC

    but since you've chosen not to answer the question;

    One possible reason (for me): to tell the truth, the first map looks a bit clunky to me. The map function is really designed to return a list. If you are using it only for its side effects on $_ and therefore on the original list, then I submit that for/foreach is a better choice. Clearer and possibly faster.

      to tell the truth, the first map looks a bit clunky to me.

      Truth is good; but "looks a bit clunky to me" doesn't cut much ice as a technical objection. It reflects only your own limited expectations.

      The map function is really designed to return a list.

      Repeating cargo cult does not make it so.

      map maps a function over a list; optionally returning a new list. Used in a void context; it does not create an output list.

      If you are using it only for its side effects on $_ and therefore on the original list, then I submit that for/foreach is a better choice.

      In the abstract, that is sound reasoning; but it concentrates on the minutia rather than the bigger picture.

      The purpose of that line of code is to apply a function: f(x) := x / (mutation rate * 100); in place, to every element of a matrix.

      The original language, Darwin, has matrix operators that allow this to be written very naturally.

      Perl does not have those operators; but does provide the tools to allow them to be written quite concisely. Thus allowing the purpose of the code; the mutation of the elements of the matrix to stand clear of the mechanics of the code required to iterate over the matrix dimensions.

      I contend that this:

      for my $aref ( @lnPAM ) { $_ /= ( $mutRate * 100 ) for @$aref; }

      Distracts from the purpose of the code, by making too great an emphasis of the (purely mechanical) process of iterating the matrix.

      Clearer and possibly faster.

      Clearer is in the eye of the beholder -- and I disagree with your view.

      Faster is a matter of benchmarking, but my guess is that there will be little in it; and it will probably favour the map version:

      @a = map[ map int(rand$_), 1 .. 10],1..10;; cmpthese -1,{ a=>q[ map $_ /= 1, @$_ for @a; ], b=>q[ for my $r( @a ){ $_ /= 1 for @$r } ], };; Rate b a b 52726/s -- -25% a 70388/s 33% --

      Yup!


      The perl code:

      while( abs( $mutRate - 0.01) > 1e-16 ) { ++$iter; $k *= $mutRate * 100; map $_ /= ( $mutRate * 100), @$_ for @lnPAM; @matrix = map[ map exp( $_ ), @$_ ], @lnPAM; $mutRate = sum map{ $freq[ $_ ] * ( 1 - $matrix[ $_ ][ $_ ] ) } 0. +.19; printf "After %d iteration(s), k=%f, RateMutation=%f\n", $iter, $k +, $mutRate; }

      was written to mirror the original Darwin code:

      while abs(RateMutation - 0.01) > DBL_EPSILON do iter := iter + 1; k:= k * RateMutation * 100: lnPAM1 := lnPAM1 / (RateMutation * 100): PAM1 := exp(lnPAM1): RateMutation := sum(Freq[i] * (1 - PAM1[i,i]), i= 1..20); printf('After %d iteration(s), k=%f, RateMutation=%f', iter, k, Ra +teMutation); od:

      as closely as possible; which I think it does admirably.

      The reason for asking the OP why he wanted it coded a different way; was so as to get some idea of how best to address his concerns when doing so.


      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.

        Truth is good; but "looks a bit clunky to me" doesn't cut much ice as a technical objection.

        It was not a technical objection, I know that using map in void context works fine. I was just expressing a matter of personal taste that it may not be the best style. Others may have different opinions on that. And I was only trying to offer a possible reason why the OP asked the question in the first place.

        It reflects only your own limited expectations.

        Yeah, I am more limited than you, sorry about that.

        Repeating cargo cult does not make it so.

        Labeling others' arguments does not make the label true. Besides, this is just rhetorics, falling short of a proper intellectual argument.

        map maps a function over a list; optionally returning a new list.

        You are sort of rewriting the official documentation to fit your argument. The documentation says:

        Evaluates the BLOCK or EXPR for each element of LIST (locally setting $_ to each element) and returns the list value composed of the results of each such evaluation.
        The map function may be used in scalar or void context, but that is definitely not its priority use. The documentation also says that map "can be used to modify the elements" of the input list, but that
        Using a regular foreach loop for this purpose would be clearer in most cases.
        Besides concentrating on the minutia of the Perl syntax is forgetting the other bigger picture that map is used in dozens of different languages and has actually been borrowed from functional programming languages to make it possible to generate a new list from an existing one in a natural fashion. There is nothing wrong using it in a different way, but it would be wrong to deny that creating a new modified list is definitely its main purpose, which you sort of do when you write "optionally returning a new list", as if it was just a secondary possible side effect of map.

        Oh, BTW, just an additional quote from the Camel Book (Programming with Style section, page 703 of the 4th edition):

        Avoid using grep, map and backticks in void context; that is when you just throw away their return values. Those functions have return values, so use them. Otherwise use a foreach loop or the system function.

        For the rest, I basically agree with the rest of your post and I generally have great respect for your opinions and carefully consider them, even when, as in the case in point, I don't entirely share them. And I upvoted your post despite a couple of things I don't like to much.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1050700]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (6)
As of 2014-08-31 07:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (294 votes), past polls