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))]
{: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
"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]
[0 1 ... | sum2]
...]
Assumes a lot of things lol"
([m]
(gaussian-elim m 0))
([m] (gaussian-elim m 0))
([m col]
(if (= col (matrix-height m))
[]
(let [steps (gaussian-column m col)
new (apply-all-at-once m steps)]
(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
[v]
(apply vector v))
(into [] v))
(defn swap-rows
"Swap rows n and m of the given matrix, 0-indexed"
@ -105,3 +105,11 @@
"Returns the number at x y in a matrix"
[m x y]
(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
(:require [matrix.base :refer :all])
(:require [clojure.string :as str]
[matrix.base :refer :all])
(:require [matrix.interactive :refer :all])
(:require [matrix.auto :refer :all])
(:require [matrix.render :refer :all])
(:gen-class))
(defn -main
"I don't do a whole lot ... yet."
[& args]
(let [got (read)]
(-> (if (number? got)
(id-matrix got)
got)
matrix-repl
last)))
(let [[steps final] (auto-steps-and-final (read))]
(println "Steps:")
;; (for [step steps]
;; (println (pretty-row-op step)))
(println (str/join "\n" (map pretty-row-op steps)))
(println "Final:")
(pprint-matrix final)))
; TODO: actual parsing of row operations
; TODO: parse equations (easy, but requires context (e.g. x = 1 could be any number of variables))
; TODO: undoing
; 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?}
; TODO: solving id-matrix
; TODO: solving gaussian-eliminated matrix
; TODO: automation
; DONE: solving id-matrix
; DONE: solving gaussian-eliminated matrix
; DONE: automation
; TODO: remove redundant row ops

View file

@ -1,6 +1,7 @@
(ns matrix.core-test
(:require [clojure.test :refer :all]
[matrix.base :refer :all]))
[matrix.base :refer :all]
[matrix.auto :refer :all]))
; TODO: more tests
@ -15,3 +16,14 @@
(testing "Multiplying by two 1x1 ident matrix"
(let [mat (id-matrix 1)]
(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]]))))))