0
votes

I am very new to Clojure and just started learning it last week. I am trying to evaluate a nested vector of vectors in this form:

[[1 2] [3 1] [-1 0]] which represents polynomials so the vector represents: x^2 + 3*x - 1 (with the first number of each set being the coefficient and the second being the exponent)

I have a function named eval-term() that takes in a number input and does the calculation of the ((number^exponent)*coefficient) for each term, so I want it to iterate through the nested vector [[1 2] [3 1] [-1 0]] and essentially evaluate [1 2] and then [3 1] and then [-1 0]

I am getting an error:

clojure.lang.Compiler$CompilerException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: user$make_poly$fn__11617, compiling:(null:53:1)
          Compiler.java:3463 clojure.lang.Compiler$InvokeExpr.eval
           Compiler.java:408 clojure.lang.Compiler$DefExpr.eval
          Compiler.java:6624 clojure.lang.Compiler.eval
          Compiler.java:6608 clojure.lang.Compiler.eval
          Compiler.java:6582 clojure.lang.Compiler.eval
               core.clj:2852 clojure.core/eval
                 eval.clj:77 lighttable.nrepl.eval/->result
                AFn.java:163 clojure.lang.AFn.applyToHelper
                AFn.java:151 clojure.lang.AFn.applyTo
                core.clj:619 clojure.core/apply
               core.clj:2396 clojure.core/partial[fn]
             RestFn.java:408 clojure.lang.RestFn.invoke
               core.clj:2487 clojure.core/map[fn]
             LazySeq.java:42 clojure.lang.LazySeq.sval
             LazySeq.java:60 clojure.lang.LazySeq.seq
                 RT.java:484 clojure.lang.RT.seq
                core.clj:133 clojure.core/seq
               core.clj:2523 clojure.core/filter[fn]
             LazySeq.java:42 clojure.lang.LazySeq.sval
             LazySeq.java:67 clojure.lang.LazySeq.seq
                Cons.java:39 clojure.lang.Cons.next
                 RT.java:598 clojure.lang.RT.next
                 core.clj:64 clojure.core/next
               core.clj:2781 clojure.core/dorun
               core.clj:2796 clojure.core/doall
                eval.clj:126 lighttable.nrepl.eval/eval-clj
             RestFn.java:442 clojure.lang.RestFn.invoke
               sonar.clj:215 lighttable.nrepl.sonar/eval5570[fn]
                AFn.java:159 clojure.lang.AFn.applyToHelper
                AFn.java:151 clojure.lang.AFn.applyTo
                core.clj:617 clojure.core/apply
               core.clj:1788 clojure.core/with-bindings*
             RestFn.java:425 clojure.lang.RestFn.invoke
               sonar.clj:203 lighttable.nrepl.sonar/eval5570[fn]
            MultiFn.java:227 clojure.lang.MultiFn.invoke
                 core.clj:98 lighttable.nrepl.core/queued[fn]
               core.clj:2330 clojure.core/comp[fn]
  interruptible_eval.clj:138 clojure.tools.nrepl.middleware.interruptible-eval/run-next[fn]
                 AFn.java:24 clojure.lang.AFn.run
ThreadPoolExecutor.java:1142 java.util.concurrent.ThreadPoolExecutor.runWorker
 ThreadPoolExecutor.java:617 java.util.concurrent.ThreadPoolExecutor$Worker.run
             Thread.java:745 java.lang.Thread.run
Caused by: java.lang.IllegalArgumentException: Don't know how to create ISeq from: user$make_poly$fn__11617
                 RT.java:505 clojure.lang.RT.seqFrom
                 RT.java:486 clojure.lang.RT.seq
                core.clj:133 clojure.core/seq
            protocols.clj:26 clojure.core.protocols/seq-reduce
            protocols.clj:41 clojure.core.protocols/fn
            protocols.clj:13 clojure.core.protocols/fn[fn]
               core.clj:6175 clojure.core/reduce
            (Unknown Source) user/make-poly
                AFn.java:161 clojure.lang.AFn.applyToHelper
                AFn.java:151 clojure.lang.AFn.applyTo
          Compiler.java:3458 clojure.lang.Compiler$InvokeExpr.eval

I think my

(defn poly-maker [polyvector]
  (reduce + #(map eval-term polyvector %))
)

is wrong because the "map" is not going through the sets in [[1 2] [3 1] [-1 0]] and evaluating them one at a time. I don't know how to resolve this, please help!

1

1 Answers

1
votes

You want something like this:

(defn poly-maker [polyvector]
  (fn [x] (reduce + (map #(eval-term % x) polyvector))))

(def example (poly-maker [[1 2] [3 1] [-1 0]]))

;TEST
(example 3)

Note that the result is 17, not 9.


Your representation is fallible: you could have two or more values for the same coefficient, for example [[1 2] [3 2]].

So use a map: power -> coefficient. For example, {2 1, 1 3, 0 -1} instead of [[1 2] [3 1] [-1 0]].