aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorMattias EngdegÄrd2019-09-22 15:03:02 +0200
committerMattias EngdegÄrd2019-09-23 11:49:55 +0200
commit73e1727c405214086bb3a0647c91855e1b0853c2 (patch)
tree8160877760c649327909662937eb0f1064375c17 /test
parentbba9757a1fd7b05f7b18b0666735711d231972fa (diff)
downloademacs-73e1727c405214086bb3a0647c91855e1b0853c2.tar.gz
emacs-73e1727c405214086bb3a0647c91855e1b0853c2.zip
Fix linear equation system solving in Calc (bug#35374)
* lisp/calc/calcalg2.el (math-try-solve-for): To solve Ax^n=0 where A is a nonzero constant and x the variable to solve for, solve x^n=0 instead of solving A=0 (which obviously fails) or something equally stupid. * test/lisp/calc/calc-tests.el (calc-test-solve-linear-system): New.
Diffstat (limited to 'test')
-rw-r--r--test/lisp/calc/calc-tests.el103
1 files changed, 103 insertions, 0 deletions
diff --git a/test/lisp/calc/calc-tests.el b/test/lisp/calc/calc-tests.el
index 8afec593b1e..3f0b65aeeef 100644
--- a/test/lisp/calc/calc-tests.el
+++ b/test/lisp/calc/calc-tests.el
@@ -138,6 +138,109 @@ An existing calc stack is reused, otherwise a new one is created."
138 (nth 1 (calcFunc-cos 1))) 138 (nth 1 (calcFunc-cos 1)))
139 0 4)))))) 139 0 4))))))
140 140
141(ert-deftest calc-test-solve-linear-system ()
142 "Test linear system solving (bug#35374)."
143 ;; x + y = 3
144 ;; 2x - 3y = -4
145 ;; with the unique solution x=1, y=2
146 (should (equal
147 (calcFunc-solve
148 '(vec
149 (calcFunc-eq (+ (var x var-x) (var y var-y)) 3)
150 (calcFunc-eq (- (* 2 (var x var-x)) (* 3 (var y var-y))) -4))
151 '(vec (var x var-x) (var y var-y)))
152 '(vec (calcFunc-eq (var x var-x) 1)
153 (calcFunc-eq (var y var-y) 2))))
154
155 ;; x + y = 1
156 ;; x + y = 2
157 ;; has no solution
158 (should (equal
159 (calcFunc-solve
160 '(vec
161 (calcFunc-eq (+ (var x var-x) (var y var-y)) 1)
162 (calcFunc-eq (+ (var x var-x) (var y var-y)) 2))
163 '(vec (var x var-x) (var y var-y)))
164 '(calcFunc-solve
165 (vec
166 (calcFunc-eq (+ (var x var-x) (var y var-y)) 1)
167 (calcFunc-eq (+ (var x var-x) (var y var-y)) 2))
168 (vec (var x var-x) (var y var-y)))))
169 ;; x - y = 1
170 ;; x + y = 1
171 ;; with the unique solution x=1, y=0
172 (should (equal
173 (calcFunc-solve
174 '(vec
175 (calcFunc-eq (- (var x var-x) (var y var-y)) 1)
176 (calcFunc-eq (+ (var x var-x) (var y var-y)) 1))
177 '(vec (var x var-x) (var y var-y)))
178 '(vec (calcFunc-eq (var x var-x) 1)
179 (calcFunc-eq (var y var-y) 0))))
180 ;; 2x - 3y + z = 5
181 ;; x + y - 2z = 0
182 ;; -x + 2y + 3z = -3
183 ;; with the unique solution x=1, y=-1, z=0
184 (should (equal
185 (calcFunc-solve
186 '(vec
187 (calcFunc-eq
188 (+ (- (* 2 (var x var-x)) (* 3 (var y var-y))) (var z var-z))
189 5)
190 (calcFunc-eq
191 (- (+ (var x var-x) (var y var-y)) (* 2 (var z var-z)))
192 0)
193 (calcFunc-eq
194 (+ (- (* 2 (var y var-y)) (var x var-x)) (* 3 (var z var-z)))
195 -3))
196 '(vec (var x var-x) (var y var-y) (var z var-z)))
197 ;; The `float' forms in the result are just artefacts of Calc's
198 ;; current solver; it should be fixed to produce exact (integral)
199 ;; results in this case.
200 '(vec (calcFunc-eq (var x var-x) (float 1 0))
201 (calcFunc-eq (var y var-y) (float -1 0))
202 (calcFunc-eq (var z var-z) 0))))
203 ;; x = y + 1
204 ;; x = y
205 ;; has no solution
206 (should (equal
207 (calcFunc-solve
208 '(vec
209 (calcFunc-eq (var x var-x) (+ (var y var-y) 1))
210 (calcFunc-eq (var x var-x) (var y var-y)))
211 '(vec (var x var-x) (var y var-y)))
212 '(calcFunc-solve
213 (vec
214 (calcFunc-eq (var x var-x) (+ (var y var-y) 1))
215 (calcFunc-eq (var x var-x) (var y var-y)))
216 (vec (var x var-x) (var y var-y)))))
217 ;; x + y + z = 6
218 ;; x + y = 3
219 ;; x - y = 1
220 ;; with the unique solution x=2, y=1, z=3
221 (should (equal
222 (calcFunc-solve
223 '(vec
224 (calcFunc-eq (+ (+ (var x var-x) (var y var-y)) (var z var-z)) 6)
225 (calcFunc-eq (+ (var x var-x) (var y var-y)) 3)
226 (calcFunc-eq (- (var x var-x) (var y var-y)) 1))
227 '(vec (var x var-x) (var y var-y) (var z var-z)))
228 '(vec
229 (calcFunc-eq (var x var-x) 2)
230 (calcFunc-eq (var y var-y) 1)
231 (calcFunc-eq (var z var-z) 3))))
232 ;; x = 3
233 ;; x + 4y^2 = 3 (ok, so this one isn't linear)
234 ;; with the unique (double) solution x=3, y=0
235 (should (equal
236 (calcFunc-solve
237 '(vec
238 (calcFunc-eq (var x var-x) 3)
239 (calcFunc-eq (+ (var x var-x) (* 4 (^ (var y var-y) 2))) 3))
240 '(vec (var x var-x) (var y var-y)))
241 '(vec (calcFunc-eq (var x var-x) 3)
242 (calcFunc-eq (var y var-y) 0)))))
243
141(provide 'calc-tests) 244(provide 'calc-tests)
142;;; calc-tests.el ends here 245;;; calc-tests.el ends here
143 246