Hi Dimiter,

Thank you! I'm still a bit confused as to why this was happening. Does
lazy evaluation not work well with recursion?

On Apr 20, 11:06 pm, "Dimiter \"malkia\" Stanev" <mal...@gmail.com>
wrote:
> I blindly tried printing out stuff from matrixMultiply, and found out
> that if I print matrixA and matrixB it doesn't run out of stack, so I
> guess I was "forcing" them to "work", here is a version with (dorun)
> that has the same side effect, without printing:
>
> (defn matrixMultiply [matrixA matrixB]
>   (dorun matrixA)
>   (dorun matrixB)
>   (map
>    (fn [row]
>      (apply map
>             (fn [& column]
>               (apply + (map * row column)))
>             matrixB))
>    matrixA))
>
> user> (main 100000)
> ((0.5 50000.5))
> user> (main 1000000)
> ((0.5 500000.5))
> user> (time (main 1000000))
> "Elapsed time: 8314.617 msecs"
> ((0.5 500000.5))
> user> (time (main 10000000))
> ; Evaluation aborted. ;; Actually not stack overflow, but HEAP
> overflow (it took a while though)
> user>
>
> Thanks,
> Dimiter "malkia" Stanev.
>
> On Apr 20, 10:01 pm, jleehurt <jleeh...@gmail.com> wrote:
>
> > Hi David,
>
> > Those two are not recursive, but they call into other functions that
> > are. Do I need to make sure that all recursive functions use the loop/
> > recur pattern? Or should I not nest recursive calls like this?
>
> > Here is the whole source:
>
> > ;; Neuron Activation Functions
>
> > ;threshold
> > (defn threshold [x] (if (>= x 0) 1 0))
>
> > ;signum (threshold)
> > (defn signum [x] (cond (> x 0) 1 (= x 0) 0 (< x 0) -1))
>
> > ;; Matrix Functions
>
> > (defn transpose [matrix]
> >   (if (not (nil? matrix))
> >       (apply map list matrix)))
>
> > (defn transpose2 [matrix]
> >   (apply map (fn [& column] column) matrix))
>
> > (defn matrixMultiply [matrixA matrixB]
> >   (map
> >     (fn [row] (apply map (fn [& column] (apply + (map * row column)))
> > matrixB))
> >     matrixA))
>
> > (defn matrixAdd [matrixA matrixB]
> >   (if (and (not (empty? matrixA)) (not (empty? matrixB)))
> >       (conj
> >         (matrixAdd (rest matrixA) (rest matrixB))
> >         (map + (first matrixA) (first matrixB)))))
>
> > (defn matrixMultiplyScalar [matrixA scalar]
> >   (if (not (empty? matrixA))
> >       (conj
> >         (matrixMultiplyScalar (rest matrixA) scalar)
> >         (map (fn [arg] (* arg scalar)) (first matrixA)))))
>
> > ;; Vector Functions
>
> > (defn transposeVector [v]
> >   (if (not (nil? v))
> >       (transpose (vector v))))
>
> > (defn vectorMultiplyScalar [v scalar]
> >   (map * v (cycle [ scalar ])))
>
> > ;; Binary Logic Input/Output
>
> > (def infiniteInputCollection (cycle [[[-1 -1]] [[-1 1]] [[1 -1]] [[1
> > 1]]]))
> > (def infiniteAndOutputCollection (cycle [-1 -1 -1 1]))
>
> > (defn buildInputs [numberOfInputs]
> >   (loop [inputVector []
> >          binaryInputCollection infiniteInputCollection
> >          remainingCount numberOfInputs]
> >         (if (> 0 remainingCount)
> >             inputVector
> >             (recur
> >               (conj inputVector (first binaryInputCollection)) (rest
> > binaryInputCollection) (dec remainingCount)))))
>
> > (defn buildOutputs [numberOfOutputs outputCollection]
> >   (loop [outputVector []
> >          andOutputCollection outputCollection
> >          remainingCount numberOfOutputs]
> >         (if (> 0 remainingCount)
> >             outputVector
> >             (recur (conj outputVector (first andOutputCollection))
> > (rest andOutputCollection) (dec remainingCount)))))
>
> > ;; Main
>
> > ;learning rate parameter eta
> > (def learningRateParameter 0.5)
>
> > ;the weight vector of the perceptron
> > (def weightVector (ref nil))
>
> > ;multiply the transpose of the weight vector with the input vector
> > ;apply the signum function to the scalar result
> > (defn computeActualResponse [signumFunction weights inputs]
> >   (if (and (not (nil? weights)) (not (nil? inputs)))
> >       (signumFunction (first (first (matrixMultiply (transpose
> > weights) inputs))))))
>
> > ;return an updated weight vector of the perceptron
> > (defn getAdaptedWeightVector [weights inputs desiredResponse
> > actualResponse]
> >   (let [etaDeltaDesiredActual (* learningRateParameter (-
> > desiredResponse actualResponse))]
> >        (matrixAdd weights (matrixMultiplyScalar inputs
> > etaDeltaDesiredActual))))
>
> > ;train the perceptron with the inputs and corresponding known outputs
> > (defn trainPerceptron [beginningWeightVector allInputs allOutputs]
> >   (loop [weightVector beginningWeightVector
> >          inputs allInputs
> >          responses allOutputs]
> >         (if (and (not (empty? inputs)) (not (empty? responses)))
> >             (let [adaptedWeightVector
> >                   (getAdaptedWeightVector
> >                     weightVector
> >                     (first inputs)
> >                     (first responses)
> >                     (computeActualResponse signum weightVector (first
> > inputs)))]
> >                  (recur adaptedWeightVector (rest inputs) (rest
> > responses)))
> >             weightVector)))
>
> > (defn main [sizeOfDataSet]
> >   (let [weights [[0 0]]
> >         inputs (buildInputs sizeOfDataSet)
> >         outputs (buildOutputs sizeOfDataSet
> > infiniteAndOutputCollection)]
> >        (trainPerceptron weights inputs outputs)))
>
> > On Apr 20, 6:32 am, David Nolen <dnolen.li...@gmail.com> wrote:> You have 
> > two other function calls
> > > getAdaptedWeightVector
> > > computeActualResponse
>
> > > Are these recursive as well?
>
> > > On Sun, Apr 19, 2009 at 11:26 PM, jleehurt <jleeh...@gmail.com> wrote:
>
> > > > Hi all, I have the following code that trains a perceptron with the
> > > > given inputs and corresponding desired inputs. For input/output
> > > > vectors, when the size gets to about 2000, I am getting a
> > > > java.lang.StackOverflowError in the following function:
>
> > > > (defn trainPerceptron [beginningWeightVector allInputs allOutputs]
> > > >  (loop [weightVector beginningWeightVector
> > > >         inputs allInputs
> > > >         responses allOutputs]
> > > >        (if (and (not (empty? inputs)) (not (empty? responses)))
> > > >            (let [adaptedWeightVector
> > > >                  (getAdaptedWeightVector
> > > >                    weightVector
> > > >                    (first inputs)
> > > >                    (first responses)
> > > >                    (computeActualResponse signum weightVector (first
> > > > inputs)))]
> > > >                 (recur adaptedWeightVector (rest inputs) (rest
> > > > responses)))
> > > >            weightVector)))
>
> > > > Is not the purpose of loop/recur to avoid stack overflow problems?
> > > > What am I doing wrong?
--~--~---------~--~----~------------~-------~--~----~
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
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to