Re: Question on eliminating recur

2011-07-13 Thread FL


On Jul 13, 1:16 am, Christian Marks 9fv...@gmail.com wrote:
 Thank you. Based on this I've simplified the code further.

You could combine the test for a cycle leader
with the cycle length count--but your original
code, which calculates cycle lengths only if
a cycle leader is identified, is more efficient!

 (ns knuth
     (:require [clojure.contrib.math :as math]))

 (defn random-perm [n]  (shuffle (range n)))

 (defn cycle-leader-length [perm i]
         (loop [cycle 1 j (nth perm i)]
                 (cond ( j i) 1
                       (= j i) cycle
                       :else     (recur (inc cycle) (nth perm j)

(defn order-perm [perm]   (reduce  (fn [order i]  (math/lcm (cycle-
leader-length perm i) order)) 1 perm))

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Question on eliminating recur

2011-07-12 Thread Christian Marks


On Jul 10, 10:16 pm, FL florian.leng...@gmail.com wrote:
\  If you replace your
...
  (defn order-perm [perm]
          (let [n (count perm)]
...
 with the more compact

 (defn order-permo [perm]
              (reduce (fn [order i] (if (= i (next-cycle-leader perm i))
                                     (math/lcm (cycle-length perm i)
 order)
                                      order))
                           1 perm))

 you'll be rewarded with better performance with permutations of size
 = 10,


Thank you. Based on this I've simplified the code further.
The (new) predicate (cycle-leader? perm i) is true if and only if
i is the least element of the unique cycle containing i
in the permutation perm. This is more readable, though the
extra test compared with the original adds to execution time.

(ns knuth
(:require [clojure.contrib.math :as math]))

(defn random-perm [n]  (shuffle (range n)))

(defn cycle-leader? [perm i]
(loop [j (nth perm i)]
(cond ( j i) false
  (= j i) true
  :else (recur (nth perm j)

(defn cycle-length [perm i]
(loop [cycle 1 j (nth perm i)]
(if (= i j)
cycle
(recur (inc cycle) (nth perm j)

(defn order-perm [perm]
   (reduce
  (fn [order i] (if (cycle-leader? perm i)
(math/lcm (cycle-length perm i) order)
order))
   1 perm))

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Question on eliminating recur

2011-07-10 Thread Joost
On Jul 10, 7:15 am, Michael Gardner gardne...@gmail.com wrote:

 I think Christian wanted to know *why* one should eliminate recur. I can't 
 think of a reason to avoid it myself, though I also don't recall hearing any 
 recommendations against using recur.

Just my two cents, but the main reason to consider map/doseq/reduce/
filter etc in favor of loop/recur is that if your algorithm matches
one of the former, you'll need a little less boiler-plate code
(sometimes), makes it easier to use/create lazy sequences and (most
importantly) using map/doseq etc when appropriate conveys a lot of
information about the structure of the algorithm and its input/output
expectations to the human reader.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Question on eliminating recur

2011-07-10 Thread FL


On Jul 9, 8:58 am, Christian Marks 9fv...@gmail.com wrote:
 The clojure code below applies the constant space algorithm ... of C. J. Gower
...  to the computation of the order of a permutation [Knuth, D. E.,
“Selected Papers on Analysis of
 Algorithms,” CSLI Lecture Notes Number 102, CSLI Publications, (2000),p 4]
...
 I'm using recur, however some clojure programmers inform me that recur
 should be eliminated in favor of doseq or fold. I see nothing wrong
 with recur myself--am I missing
 something?



Not much. If you replace your

 (defn order-perm [perm]
         (let [n (count perm)]
                 (loop [i 0 order 1]
                         (if (= i n)
                                 order
                             (recur (inc i)
                                    (if (= i (next-cycle-leader perm i))
                                                      (math/lcm (cycle-length 
 perm i) order)
                               order))

with the more compact

(defn order-permo [perm]
 (reduce (fn [order i] (if (= i (next-cycle-leader perm i))
(math/lcm (cycle-length perm i)
order)
 order))
  1 perm))

you'll be rewarded with better performance with permutations of size
= 10,
and slightly worse performance with larger permutations:


knuth= (load knuth)
nil
knuth= (ns knuth)
nil
knuth= (def p (random-perm 10))
#'knuth/p
knuth= (time (order-perm p))
Elapsed time: 958.706617 msecs
8124696972786944584881000
knuth= (time (order-permo p))
Elapsed time: 908.262712 msecs
8124696972786944584881000
knuth= (def p (random-perm 100))
#'knuth/p
knuth= (time (order-perm p))
Elapsed time: 14699.019199 msecs
12165632849310917835084160
knuth= (time (order-permo p))
Elapsed time: 15338.770595 msecs
12165632849310917835084160
knuth=

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Question on eliminating recur

2011-07-09 Thread Christian Marks
The clojure code below applies the constant space algorithm to apply a
permutation to an array of C. J. Gower to the computation of the order
of a permutation [Knuth, D. E., “Selected Papers on Analysis of
Algorithms,” CSLI Lecture Notes Number 102, CSLI Publications, (2000),
p 4]. The order of a permutation is the least common multiple of its
cycle lengths; the function order-perm below makes use of the
associativity of the least common multiple.

I'm using recur, however some clojure programmers inform me that recur
should be eliminated in favor of doseq or fold. I see nothing wrong
with recur myself--am I missing
something?

(ns knuth
(:require [clojure.contrib.math :as math]))

(defn random-perm [n]  (shuffle (range n)))

(defn next-cycle-leader [perm i]
(loop [j (nth perm i)]
(if (= j i)
j
(recur (nth perm j)

(defn cycle-length [perm i]
(loop [cycle 1 j (nth perm i)]
(if (= i j)
cycle
(recur (inc cycle) (nth perm j)

(defn order-perm [perm]
(let [n (count perm)]
(loop [i 0 order 1]
(if (= i n)
order
(recur (inc i)
   (if (= i (next-cycle-leader perm i))
 (math/lcm (cycle-length 
perm i) order)
  order))

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Question on eliminating recur

2011-07-09 Thread Brian Hurt
On Sat, Jul 9, 2011 at 8:58 AM, Christian Marks 9fv...@gmail.com wrote:


 I'm using recur, however some clojure programmers inform me that recur
 should be eliminated in favor of doseq or fold. I see nothing wrong
 with recur myself--am I missing
 something?


If there is an obvious way to rewrite the code using doseq or fold (or
reduce or map or etc), then yes- you should do it.  However, if this way to
rewrite the code isn't obvious in 10 seconds of thought, don't worry about
it. Use loop/recur.  The goal is clear, concise code- not blind obedience to
aphorisms.

Brian

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: Question on eliminating recur

2011-07-09 Thread Michael Gardner
On Jul 9, 2011, at 8:47 AM, Brian Hurt wrote:

 If there is an obvious way to rewrite the code using doseq or fold (or reduce 
 or map or etc), then yes- you should do it.  However, if this way to rewrite 
 the code isn't obvious in 10 seconds of thought, don't worry about it. Use 
 loop/recur.  The goal is clear, concise code- not blind obedience to 
 aphorisms.

I think Christian wanted to know *why* one should eliminate recur. I can't 
think of a reason to avoid it myself, though I also don't recall hearing any 
recommendations against using recur.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en