automation basically done

This commit is contained in:
mehbark 2023-01-15 20:21:25 -05:00
parent 52422563b1
commit 3b998c060b
4 changed files with 71 additions and 15 deletions

View file

@ -35,18 +35,50 @@
(for [y (range (inc col) (matrix-height m))] (for [y (range (inc col) (matrix-height m))]
{:add-row col :times (- (at m col y)) :to-row y})))) {:add-row col :times (- (at m col y)) :to-row y}))))
; TODO: make-gaussian-eliminable, which swaps rows so that they can actually be gaussian-elim'd
(defn gaussian-elim (defn gaussian-elim
"Takes a matrix and returns the steps to put in the form "Takes a matrix and returns the steps to put it in the form
[[1 a ... | sum1] [[1 a ... | sum1]
[0 1 ... | sum2] [0 1 ... | sum2]
...] ...]
Assumes a lot of things lol" Assumes a lot of things lol"
([m] ([m] (gaussian-elim m 0))
(gaussian-elim m 0))
([m col] ([m col]
(if (= col (matrix-height m)) (if (= col (matrix-height m))
[] []
(let [steps (gaussian-column m col) (let [steps (gaussian-column m col)
new (apply-all-at-once m steps)] new (apply-all-at-once m steps)]
(concat steps (gaussian-elim new (inc col))))))) (concat steps (gaussian-elim new (inc col)))))))
(defn back-sub-column
[m col]
(for [y (range 0 col)]
{:add-row col
:times (- (at m col y))
:to-row y}))
; idea: clear backwards
(defn back-sub
"Takes a gaussian-eliminated matrix and returns the steps to make the id matrix on the left side"
([m] (back-sub m (dec (matrix-height m))))
([m col]
(if (zero? col)
[]
(let [steps (back-sub-column m col)
new (apply-all-at-once m steps)]
(println new)
(concat steps (back-sub new (dec col)))))))
(defn auto-steps-and-final
[m]
(let [g-elim-steps (gaussian-elim m)
after-g-elim (apply-all-at-once m g-elim-steps)
bsub-steps (back-sub after-g-elim)
after-bsub (apply-all-at-once after-g-elim bsub-steps)]
[(concat g-elim-steps bsub-steps)
after-bsub]))
(def auto-steps (comp first auto-steps-and-final))
(def auto-final (comp last auto-steps-and-final))

View file

@ -3,7 +3,7 @@
(defn to-vec (defn to-vec
[v] [v]
(apply vector v)) (into [] v))
(defn swap-rows (defn swap-rows
"Swap rows n and m of the given matrix, 0-indexed" "Swap rows n and m of the given matrix, 0-indexed"
@ -105,3 +105,11 @@
"Returns the number at x y in a matrix" "Returns the number at x y in a matrix"
[m x y] [m x y]
(get (get m y) x)) (get (get m y) x))
(defn map-matrix
([f] #(map-matrix f %))
([f m]
(->> m
(map #(map f %))
(map to-vec)
to-vec)))

View file

@ -1,24 +1,28 @@
(ns matrix.core (ns matrix.core
(:require [matrix.base :refer :all]) (:require [clojure.string :as str]
[matrix.base :refer :all])
(:require [matrix.interactive :refer :all]) (:require [matrix.interactive :refer :all])
(:require [matrix.auto :refer :all]) (:require [matrix.auto :refer :all])
(:require [matrix.render :refer :all])
(:gen-class)) (:gen-class))
(defn -main (defn -main
"I don't do a whole lot ... yet." "I don't do a whole lot ... yet."
[& args] [& args]
(let [got (read)] (let [[steps final] (auto-steps-and-final (read))]
(-> (if (number? got) (println "Steps:")
(id-matrix got) ;; (for [step steps]
got) ;; (println (pretty-row-op step)))
matrix-repl (println (str/join "\n" (map pretty-row-op steps)))
last))) (println "Final:")
(pprint-matrix final)))
; TODO: actual parsing of row operations ; TODO: actual parsing of row operations
; TODO: parse equations (easy, but requires context (e.g. x = 1 could be any number of variables)) ; TODO: parse equations (easy, but requires context (e.g. x = 1 could be any number of variables))
; TODO: undoing ; TODO: undoing
; will have to have a higher level thing for storing state ; will have to have a higher level thing for storing state
; use a set for options on the higher-level thing #{:show-equations? :show-bar? :color?} ; use a set for options on the higher-level thing #{:show-equations? :show-bar? :color?}
; TODO: solving id-matrix ; DONE: solving id-matrix
; TODO: solving gaussian-eliminated matrix ; DONE: solving gaussian-eliminated matrix
; TODO: automation ; DONE: automation
; TODO: remove redundant row ops

View file

@ -1,6 +1,7 @@
(ns matrix.core-test (ns matrix.core-test
(:require [clojure.test :refer :all] (:require [clojure.test :refer :all]
[matrix.base :refer :all])) [matrix.base :refer :all]
[matrix.auto :refer :all]))
; TODO: more tests ; TODO: more tests
@ -15,3 +16,14 @@
(testing "Multiplying by two 1x1 ident matrix" (testing "Multiplying by two 1x1 ident matrix"
(let [mat (id-matrix 1)] (let [mat (id-matrix 1)]
(is (= [[2]] (mul-row mat 2 0)))))) (is (= [[2]] (mul-row mat 2 0))))))
(deftest test-auto
(testing "1 variable equation"
(is (= [[1 10]] (auto-final [[2 20]]))))
(testing "2 variable equation"
(is (= [[1 0 3]
[0 1 3]]
(map-matrix int
(auto-final
[[2 3 15]
[1 -1 0]]))))))