-
Notifications
You must be signed in to change notification settings - Fork 140
/
equations.jl
95 lines (78 loc) · 2.34 KB
/
equations.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
"""
$(TYPEDEF)
An equality relationship between two expressions.
# Fields
$(FIELDS)
"""
struct Equation
"""The expression on the left-hand side of the equation."""
lhs
"""The expression on the right-hand side of the equation."""
rhs
function Equation(lhs, rhs)
new(value(lhs), value(rhs))
end
end
Base.:(==)(a::Equation, b::Equation) = all(isequal.((a.lhs, a.rhs), (b.lhs, b.rhs)))
Base.hash(a::Equation, salt::UInt) = hash(a.lhs, hash(a.rhs, salt))
Base.show(io::IO, eq::Equation) = print(io, eq.lhs, " ~ ", eq.rhs)
SymbolicUtils.simplify(x::Equation; kw...) = simplify(x.lhs; kw...) ~ simplify(x.rhs; kw...)
function SymbolicUtils.substitute(x::Equation, rules; kw...)
sub = substituter(rules)
sub(x.lhs; kw...) ~ sub(x.rhs; kw...)
end
lhss(xs) = map(x->x.lhs, xs)
rhss(xs) = map(x->x.rhs, xs)
"""
$(TYPEDSIGNATURES)
Create an [`Equation`](@ref) out of two [`Num`](@ref) instances, or an
`Num` and a `Number`.
# Examples
```jldoctest
julia> using Symbolics
julia> @variables x y;
julia> @variables A[1:3, 1:3] B[1:3, 1:3];
julia> x ~ y
x ~ y
julia> x - y ~ 0
x - y ~ 0
julia> A ~ B
(broadcast(~, A, B))[1:3,1:3]
julia> A .~ 3x
(broadcast(~, A, 3x))[1:3,1:3]
```
"""
function Base.:~(lhs, rhs)
if isarraysymbolic(lhs) || isarraysymbolic(rhs)
if isarraysymbolic(lhs) && isarraysymbolic(rhs)
lhs .~ rhs
else
throw(ArgumentError("Cannot equate an array with a scalar. Please use broadcast `.~`."))
end
else
Equation(lhs, rhs)
end
end
for T in [:Num, :Complex, :Number], S in [:Num, :Complex, :Number]
(T != :Complex && S != :Complex) && continue
@eval Base.:~(a::$T, b::$S) = let ar = value(real(a)), br = value(real(b)),
ai = value(imag(a)), bi = value(imag(b))
if ar isa Number && br isa Number && ai isa number && bi isa Number
error("Equation $a ~ $b does not contain any symbols")
elseif ar isa Number && br isa Number
ai ~ bi
elseif ai isa Number && bi isa Number
ar ~ br
else
[ar ~ br
ai ~ bi]
end
end
end
struct ConstrainedEquation
constraints
eq
end
function expand_derivatives(eq::Equation, simplify=false)
return Equation(expand_derivatives(eq.lhs, simplify), expand_derivatives(eq.rhs, simplify))
end