Hi David, Those two are not recursive, but they call into other recursive functions. Do I need to make sure all recursive functions use the loop/ recur pattern? Or maybe not nest recursive calls like this?
Here is the whole source: ;threshold (defn threshold [x] (if (>= x 0) 1 0)) ;signum (threshold) (defn signum [x] (cond (> x 0) 1 (= x 0) 0 (< x 0) -1)) ;piecewise linear (defn piecewise [x] (cond (>= x 0.5) 1 (and (> x -0.5) (< x 0.5)) x (<= x -0.5) 0)) ;logistic (sigmoidal) (defn sigmoid [x slopeParameter] (/ 1 (+ 1 (Math/exp (* -1 (* x slopeParameter)))))) ;hyberbolic tangent (sigmoidal) (defn hyperbolicTangent [x] (Math/tanh x)) ;arctangent (sigmoidal) (defn arcTangent [x] (Math/atan x)) ;gompertz curve (sigmoidal) ; a is the upper asymptote ; c is the growth rate ; b, c are negative numbers (defn gompertzCurve [x a b c] (* a (Math/pow Math/E (* b (Math/pow Math/E (* c x)))))) ;algebraic sigmoid (defn algebraicSigmoid [x] (/ x (Math/sqrt (+ 1 (Math/pow x 2))))) ;; 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))) ;;TODO create a function that will apply first to a collection until the inner item is obtained (signumFunction (first (first (matrixMultiply (transpose weights) inputs)))))) (defn computeActualResponse2 [signumFunction weights inputs] ;;(if (and (not (nil? weights)) (not (nil? inputs))) ;;(signumFunction (first (first (matrixMultiply (transpose weights) inputs)))))) 4) ;return an updated weight vector of the perceptron (defn getAdaptedWeightVector [weights inputs desiredResponse actualResponse] (let [etaDeltaDesiredActual (* learningRateParameter (- desiredResponse actualResponse))] (matrixAdd weights (matrixMultiplyScalar inputs etaDeltaDesiredActual)))) ;;(dosync (ref-set weightVector newWeights)))) (defn getAdaptedWeightVector2 [weights inputs desiredResponse actualResponse] (let [etaDeltaDesiredActual (* learningRateParameter (- desiredResponse actualResponse)) scaledResponses (matrixMultiplyScalar inputs etaDeltaDesiredActual)] (matrixAdd weights [[0 0]]))) ;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 trainPerceptron2 [beginningWeightVector allInputs allOutputs] (loop [inputs allInputs responses allOutputs] (if (or (empty? inputs) (empty? responses)) (deref weightVector) bv(dosync (ref-set weightVector (matrixAdd (deref weightVector) (deref weightVector)))) (recur (rest inputs) (rest responses))))) (defn main [sizeOfDataSet] (let [weights [[0 0]] inputs (buildInputs sizeOfDataSet) outputs (buildOutputs sizeOfDataSet infiniteAndOutputCollection)] (trainPerceptron weights inputs outputs))) (defn main-test [sizeOfDataSet] (let [weights [[0 0]] inputs (buildInputs sizeOfDataSet) outputs (buildOutputs sizeOfDataSet infiniteAndOutputCollection)] (trainPerceptron2 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 -~----------~----~----~----~------~----~------~--~---