2011-08-12 17 views
5

versión más simple:Cómo sumar varios vectores de algunas estructuras en Clojure

Esto funciona:

user=> (map + [1 2 3] [4 5 6] [7 8 9]) 
(12 15 18) 

Esto no es así:

user=> (for [n (range 3)] [n (+ 1 n)]) 
([0 1] [1 2] [2 3]) 
user=> (map + (for [n (range 3)] [n (+ 1 n)])) 
java.lang.ClassCastException 

¿Por qué?


Soy muy nuevo en clojure por lo que este es probablemente un error novato. En el siguiente código, intento agregar varias señales juntas. Cada señal contiene un vector (llamado datos) y quiero hacer una adición por partes. Al REPL, algo como esto:

user=> (map + [1 2 3] [4 5 6] [7 8 9]) 
(12 15 18) 

Mi código es el siguiente:

(defrecord signal [x y data]) 
(defrecord sampling [t0 dt n]) 

(defn random-signal [x y sampling tstart tend] 
    (let [t0 (:t0 sampling) 
     dt (:dt sampling) 
     n (:n sampling) 
     random-or-zero (fn [i] 
         (let [t (+ t0 (* dt i))] 
          (if (and (>= t tstart) (< t tend)) (- (* 2 (rand)) 1) 0))) 
     data (vec (for [i (range n)] (random-or-zero i)))] 
    (signal. x y data))) 

(defn add-signals [signals] 
    (let [s0 (nth signals 0)] 
    (signal. (:x s0) (:y s0) (vec (map + (for [s signals] (:data s))))))) 

(let [s (sampling. 0 0.1 10) 
    r1 (random-signal 5 6 s 0.3 0.5) 
    r2 (random-signal 5 6 s 0 1)] 
    (prn r1) 
    (prn r2) 
    (prn (add-signals [r1 r2]))) 

El código de señal aleatoria funciona bien, pero el código de falla en el "mapa +" con una excepción de difusión de clases . Por lo que la salida (inútil) es:

#:com.xxx.signal{:x 5, :y 6, :data [0 0 0 0.347104804641861 -0.043159177718418595 0 0 0 0 0]} 
#:com.xxx.signal{:x 5, :y 6, :data [0.4956475276522727 -0.5843463943909746 -0.3375682325118188 0.5082971115650308 -0.971067613756232 0.6002887290735672 0.06900015064406251 -0.49986294956362287 0.657705242728329 0.7737992261031372]} 
Exception in thread "main" java.lang.RuntimeException: java.lang.ClassCastException (fake.clj:0) 
    at clojure.lang.Compiler.eval(Compiler.java:5440) 
    at clojure.lang.Compiler.load(Compiler.java:5857) 
    at clojure.lang.Compiler.loadFile(Compiler.java:5820) 
    at clojure.main$load_script.invoke(main.clj:221) 
    at clojure.main$script_opt.invoke(main.clj:273) 
    at clojure.main$main.doInvoke(main.clj:354) 
    at clojure.lang.RestFn.invoke(RestFn.java:408) 
    at clojure.lang.Var.invoke(Var.java:365) 
    at clojure.lang.AFn.applyToHelper(AFn.java:161) 
    at clojure.lang.Var.applyTo(Var.java:482) 
    at clojure.main.main(main.java:37) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) 
Caused by: java.lang.RuntimeException: java.lang.ClassCastException 
    at clojure.lang.LazySeq.sval(LazySeq.java:47) 
    at clojure.lang.LazySeq.seq(LazySeq.java:56) 
    at clojure.lang.RT.seq(RT.java:450) 
    at clojure.lang.LazilyPersistentVector.create(LazilyPersistentVector.java:31) 
    at clojure.core$vec.invoke(core.clj:318) 
    at com.xxx.fake$add_signals.invoke(fake.clj:60) 
    at com.xxx.fake$eval223.invoke(fake.clj:74) 
    at clojure.lang.Compiler.eval(Compiler.java:5424) 
    ... 15 more 
Caused by: java.lang.ClassCastException 
    at java.lang.Class.cast(Class.java:2990) 
    at clojure.core$cast.invoke(core.clj:293) 
    at clojure.core$_PLUS_.invoke(core.clj:815) 
    at clojure.core$map$fn__3699.invoke(core.clj:2094) 
    at clojure.lang.LazySeq.sval(LazySeq.java:42) 
    ... 22 more 

Process finished with exit code 1 

¿Qué estoy haciendo mal?

+0

Resulta que necesitaba usar 'apply' para la versión con' for'. –

Respuesta

2

Esto no funcionará,

porque ahora está de paso mapa, siguientes de SEQs (SEC uno en contraposición a 3 para el primer ejemplo),

esto es igual a,

(map + [[1 2 3] [4 5 6] [7 8 9]]) 

si lo hace,

(apply map + (for [n (range 3)] [n (+ 1 n)])) 

se evaluará a,

(map + [0 1] [1 2] [2 3]) 
+0

sí, lo sé, gracias. Publiqué la respuesta yo mismo, pero fue eliminada. –

+0

, pero supongo que también podría tener los puntos de todos modos :) –

Cuestiones relacionadas