Skip to content

Commit d436d72

Browse files
committed
Auto-distribute -1 into parentheses, -(a + b) = -a - b
1 parent d64b399 commit d436d72

File tree

3 files changed

+12
-7
lines changed

3 files changed

+12
-7
lines changed

src/Symbolics/Expression.fs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@ module Operators =
298298
| x -> Product (List.rev x)
299299

300300
/// Multiply a number with an expression (potentially a denormalized product)
301+
/// Intentionally distribte -1, e.g. -(a + b) = -a - b
301302
let rec valueMul (v:Value) x =
302303
if Value.isZero v then zero else
303304
match x with
@@ -306,6 +307,9 @@ module Operators =
306307
| Product [a] -> if Value.isOne v then a else Product [Values.unpack v; a]
307308
| Product ((Values.Value a)::ax) -> valueMul (Value.product (a,v)) (Product ax)
308309
| Product ax -> if Value.isOne v then x else Product (Values.unpack v::ax)
310+
| Sum ax as x'-> if Value.isOne v then x'
311+
else if Value.isMinusOne v then ax |> List.map (function xi -> valueMul v xi) |> Sum
312+
else Product [Values.unpack v; x']
309313
| x -> if Value.isOne v then x else Product [Values.unpack v; x]
310314

311315
match x, y with

src/SymbolicsUnitTests/Operators/Exponential.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ let tests =
1818
}
1919

2020
test "Special Values" {
21-
exp(x + y - (x + y)) ==> "exp(x + y - (x + y))" // "1"
21+
exp(x + y - (x + y)) ==> "1"
2222

2323
exp(-1Q) ==> "1/e"
2424
exp(1Q/2Q*pi*Constant I) ==> "j"

src/SymbolicsUnitTests/Tests.fs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -237,12 +237,13 @@ let tests =
237237

238238
test "Algebraic Expansion" {
239239

240-
// Auto-simplification does not expand expressions:
241-
(a+b)-(a+b) ==> "a + b - (a + b)"
240+
// Auto-simplification does not expand expressions, but -1 distributes inside parentheses:
241+
(a+b)-(a+b) ==> "0"
242242
(a+b)-(a+b) |> Algebraic.expand ==> "0"
243-
2*(a+b)-(a+b) ==> "a + b"
243+
2*(a+b)-(a+b) ==> "-a - b + 2*(a + b)"
244244
(a+b)-2*(a+b) |> Algebraic.expand ===> "(-1)*a + (-1)*b"
245245
(a+b)-2*(a+b) |> Algebraic.expand ==> "-a - b"
246+
-(a + b) + 2*(a + b) ==> "-a - b + 2*(a + b)"
246247

247248
(a*b)/(b*a) ==> "1"
248249
(a*b)**2/(b*a) ==> "a*b"
@@ -285,7 +286,7 @@ let tests =
285286

286287
test "Algebaric Operators" {
287288

288-
negate (x + y**2) ==> "-(x + y^2)"
289+
negate (x + y**2) ==> "-x - y^2"
289290

290291
Algebraic.factors (b*cos(x)*ln(d)*x) ==+> ["b"; "x"; "ln(d)"; "cos(x)"]
291292
Algebraic.factors (b*cos(x)*log10(d)*x) ==+> ["b"; "x"; "log(d)"; "cos(x)"]
@@ -402,7 +403,7 @@ let tests =
402403

403404
// TODO: expected: 0
404405
Trigonometric.simplify (sin(x) + sin(y) - 2*sin(x/2+y/2)*cos(x/2-y/2))
405-
==> "sin(y) - sin(x - y)/2 - sin(x/2 - y/2 - (x/2 - y/2))/2 - sin(-x/2 + y/2 - (x/2 - y/2))/2 - sin(x/2 + y/2 - (x/2 - y/2))"
406+
==> "-sin(-x + y)/2 - sin(x - y)/2" // "0"
406407
}
407408

408409
test "Differentiation and Taylor Series" {
@@ -482,7 +483,7 @@ let tests =
482483
solve x (2+3*x) ==> "-2/3"
483484

484485
// sin(a)+x*cos(b)+c = 0 --> x =
485-
solve x (sin(a)+x*cos(b)+c) ==> "-(c + sin(a))/cos(b)"
486+
solve x (sin(a)+x*cos(b)+c) ==> "(-c - sin(a))/cos(b)"
486487

487488
// (x^2-1)/(x+1) = 0 --> x =
488489
solve x ((x**2-1)/(x+1)) ==> "1"

0 commit comments

Comments
 (0)