1

I'm working on a Clojure project that takes as an input an array a, and finds the minimum in the range [i,j] for each i, j, in O(n) preproccessing, and O(1) for each query. (preproccessing takes O(n*log(n)), but by using concurrency (pmap) and dividing the array to n/log n arrays we can solve this problem in O(n))

So, I choce to represent the array as a vector, and the matrix as vector of vectors.

This is one of the functions in C#:

    void build_RMQ_log(int[] a)
    {
        ST = new int[2 * a.Length][];
        for (int i = 0; i < 2 * a.Length; i++)
            ST[i] = new int[(int)Math.Log(a.Length, 2)];

        for (int i = 0; i < a.Length; i++)
        {
            ST[i][0] = i;
            ST[i + a.Length - 1][0]=0;
        }

        for (int j = 1; j < (int)Math.Log(a.Length, 2); j++)
        {
            for (int i = 0; i < a.Length; i++)
            {
                if (a[ST[i][j - 1]] <= a[ST[i + (int)Math.Pow(2, j - 1)][j - 1]])
                    ST[i][j] = ST[i][j - 1];
                else
                    ST[i][j] = ST[i + (int)Math.Pow(2, j - 1)][j - 1];
            }
        }
    }
    i

And this is how I wrote it in Clojure:

    ;build_RMQ_log(int[] a)

    (defn check [row1 row2 arr j]
                  (let [x1 (nth arr (nth row1 j))
                    x2 (nth arr (nth row2 (- j 1)))
                    x3 (nth arr (nth row1 (- j 1)))]

                  (if (<= x1 x2)
                     (assoc row1 j (nth row1 (- j 1)))
                     (assoc row1 j (nth row2 (- j 1))))))

    (defn apply_fn [ST a row r]
    (let [len (count a)
     cnt (/ len (log_ len 2))]
      (loop[ii 0 r 0]
        (if (= ii (- cnt 1))
          ST
         (recur (inc ii) (check row (nth ST (+ r (Math/pow 2 (- ii 1)))) a ii))))))


   (defn build_RMQ_log [a]
     (let [len (count a)
           ST (diag_n_m len (log_ len 2))
           r 0]
     (pmap  (fn [row] (apply_fn (ST a row r))) ST )))

First of all, when i try to run it, it shows me this error:

    #<IllegalArgumentException java.lang.IllegalArgumentException: Wrong number of  args (3) passed to: PersistentVector>

besides, The code that I wrote doesn't do what I want, because I dont know how can I change the value of r (that represents the row number) if apply_fn works in parallel. I.e. like it changes in c#:

for (int i = 0; i < a.Length; i++)

(r is like i in the for-loop in c#)

Thanks in Advance.

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
Howaida Khoureieh
  • 519
  • 2
  • 11
  • 24
  • Presumably this is the same issues as this one: http://stackoverflow.com/questions/9261473/rmq-function-implementation I would suggest that you try to implement the function without parallelism first, and then modify it to use `pmap` once you've first got it working properly. – liwp Feb 14 '12 at 09:50
  • We've tried, again, got the same error and didn't know how to change the value of "r" ! would appreciate your help ! – Howaida Khoureieh Feb 14 '12 at 10:12

1 Answers1

2

If I undestand you correctly, you want to pass an incrementing r to each call of apply_fn. You could try this:

(defn build_RMQ_log [a]
  (let [len (count a)
        ST (diag_n_m len (log_ len 2))
        rs (range)]
    (pmap  (fn [row r] (apply_fn (ST a row r))) ST rs)))

That is, you're passing two collections to pmap where the second collection is an infinite collection of increasing integers (i.e. [0, 1, 2, 3, ...]).

liwp
  • 6,746
  • 1
  • 27
  • 39
  • Thanks alot, that solved my second problem.I added the following code: (defn inc_int_arr [x] (def m3 []) (def x1 (dec x)) (loop[i 0] (if(and (not(= (def m3 (conj m3 i)) [])) (= i x1)) m3 (recur (inc i))))) (defn build_RMQ_log [a] (let [len (count a) ST (diag_n_m len (log_ len 2)) r (inc_int_arr len)] (pmap (fn [row r] (apply_fn (ST a row r)))ST))) This should work, still, it shows me the following error when i try to run build_RMQ_log: # – Howaida Khoureieh Feb 14 '12 at 11:08
  • Your `pmap` call passes only one argument to the `(fn)` which is expecting two arguments. Also, please stop using `def` inside function definitions. – liwp Feb 14 '12 at 11:15
  • Right. Well, Its my First project in Clojure. Thanks for your help, Hope it works now. – Howaida Khoureieh Feb 14 '12 at 12:17