Advertisement
Guest User

Untitled

a guest
Jan 19th, 2016
179
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (ns myapp.sm
  2.   (:require [clojure.core.matrix :as matr])
  3.   (:use [clojure.test]))
  4.  
  5. (def m-zero {1 [[0]]
  6.              2 (matr/matrix [[0 0] [0 0]])
  7.              3 (matr/matrix [[0 0 0] [0 0 0] [0 0 0]])})
  8.  
  9. (defn empty-m [dim]
  10.   "return a dim x dim matrix of zeroes"
  11.   (if (<= 3 dim)
  12.     (get m-zero dim)
  13.     (matr/matrix (vec (take dim (cycle [(take dim (cycle [0]))]))))))
  14.  
  15.  
  16. (defn m-sqrt [[[A B] [C D]]]
  17.   "Calculates one square root of a 2x2 matrix"
  18.   (let [[a b c d] (map #(Math/sqrt %) [A B C D])]
  19. ;    (println "Matrix:\n" [A B] \newline [C D] \newline a b c d)
  20.         (cond
  21.           (and (zero? B) (zero? C) (not (zero? A)) (not (zero? D)))
  22.           (matr/matrix [[a 0] [0 d]])
  23.          
  24.           (and (zero? B) (every? #(not (zero? %)) [A C D]))
  25.           (matr/matrix [[a 0] [(/ C (+ a d)) c]])
  26.          
  27.           (and (zero? C) (every? #(not (zero? %)) [A B D]))
  28.           (matr/matrix [[a (/ B (+ a d))] [0 d]])
  29.  
  30.           :default
  31.           (let [tau (+ A D)
  32.                 sigma (- (* A D) (* B C))]
  33.             (cond
  34.               (and (zero? sigma) (zero? tau))
  35.               (empty-m 2)
  36.  
  37.               :default
  38.               (let [s (Math/sqrt sigma)
  39.                     t (Math/sqrt (+ tau (* 2 s)))]
  40.                 (println "s" s "t" t)
  41.                 (matr/div (matr/matrix [[(+ A s) B] [C (+ D s)]]) t)))))))
  42.  
  43.  
  44. (defn- to-matrix [v & col]
  45.   "Transform a vector to a matrix for required format"
  46.   (let [n (count v)]
  47.     (if col
  48.       (matr/set-column (empty-m n) 0 v)
  49.       (matr/set-row (empty-m n) 0 v))))
  50.  
  51. (defn com
  52.   "Calculate center of mass"
  53.   ([[x m]] (com x m))
  54.   ([x m]
  55.    {;^:doc "Calculate center of mass"
  56.     :pre [(obj-valid? x m)]}
  57.     (matr/mmul (reduce matr/add (map matr/mmul x m))
  58.                (/ 1 (reduce + m)))))
  59.  
  60.  
  61. (defn body [x m a]
  62.   {:x0 x
  63.    :x x
  64.    :m m
  65.    :t0 (com x m)
  66.    :v (take (count m) (cycle [0]))
  67.    :alpha a})
  68.  
  69.  
  70. (defn- de-singularise [M]
  71.   "Neccessary do avoid ugly singularities"
  72.   (if-not (zero? (matr/det M))
  73.     M
  74.     (matr/matrix
  75.      (for [i (range (count M))]
  76.        (vec (for [j (range (count M))]
  77.               (let [mij (get-in M [i j])]
  78.                 (if (and (= i j) (zero? mij)) 1e16
  79.                     mij))))))))
  80.  
  81.  
  82. (defn goal [{:keys [x x0 m t0]}]
  83.   "calculate goal posititions gi for points x of body b"
  84.   (let [t (com x m)
  85.         p (map matr/sub x t)
  86.         q (map matr/sub x0 t0)
  87.         Apq (reduce matr/add
  88.                     (map matr/mul
  89.                          (map to-matrix p)
  90.                          (map #(to-matrix % :transpose) q)))
  91.         S (m-sqrt (matr/mmul (matr/transpose Apq) Apq))
  92.         S (de-singularise S)
  93.         R (matr/mmul Apq (matr/inverse S))
  94.         t0 (matr/mmul t0 (matr/identity-matrix (count (first x))))
  95.         delta (map #(matr/sub % t0) x)]
  96. ;    (println "R:"  R "delta:" delta)
  97.     (map #(matr/add % t)
  98.          (map #(matr/mmul R %) delta))))
  99.  
  100. (defn advance [{:keys [x v alpha] :as b} h]
  101.   (let [g (goal b)
  102.         delta (map matr/sub g x)
  103.         delta (map #(matr/mmul (/ alpha h) %) delta)
  104.         v (map matr/add v delta)
  105.         v (map #(matr/mmul % h) v)
  106.         x (map matr/add x v)]
  107.     (assoc b :x x :v v)))
  108.  
  109. (deftest shape-matching
  110.   (let [x0 [[0 0] [0 5] [5 5] [5 0]]
  111.         x1 (matr/add 1 x0)
  112.         m [1 1 1 1]
  113.         b (assoc (body x0 m 0.5) :x x1)]
  114.     (println "Body:\n" (clojure.string/join \newline b) \newline)
  115.     (println (com x0 m))
  116.     (println "goal:" (goal b))
  117.     (loop [the-body b
  118.            n 0]
  119.       (when (< n 6)
  120.         (println "step" n)
  121.         (println (clojure.string/join \newline the-body))
  122.         (recur (advance the-body 0.01)
  123.                (inc n))))))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement