# Symbolics.jl problem trying to use solve_for

I’m learning how to use Symbolcs.jl.

My current work involves lines and vectors in three dimensional space.

At the suggestion of, I think Shash, at a CAJUN about a month ago, since the Symbolics variables as introduced by `@variables` are scalars, I’ve defined

``````"""
symbolic_vector(name::Symbol, n::Integer)

Define `n` Symbolics variables hose names are based on `name` and
return a vector of those variables.
"""
function symbolic_vector(name::Symbol, n::Integer)
eltname(name, i) = Symbol("(\$name)_\$i")
map(variable, map(i -> eltname(name, i), 1:n))
end
``````

to define “vector variables”, and

``````"""
vsubs(v::Vector{Symbolics.Num}, values...)

Return a list of `Pair`s suitable for constructing a `Dict` which is
suitable for passing to `Symbolics.substitute`, which
substitues each of `values` with the corresponding variable in `v`.
"""
function vsubs(v::Vector{Symbolics.Num}, values...)
Pair.(v, values)
end
``````

to swubstitute values for them.

I also provide qa cnvenience function for creating the parameteric formula for a line:

``````"""
line(p1, p2, param)

Return the parametric formula for a point on a line which passes through points `p1` and `p2`, and has `param`.
"""
function line(p1, p2, param)
p1 + param * (p2 - p1)
end
``````

As a simple example, I’m trying to find the point at which two copla\nar lines intersect:

``````P1 = symbolic_vector(:P1, 3)
P2 = symbolic_vector(:P2, 3)
P3 = symbolic_vector(:P3, 3)
P4 = symbolic_vector(:P4, 3)
@variables r, s
L1 = line(P1, P2, r)
L2 = line(P3, P4, s)
# L1 and L2 intersect at the point where their formulas are equal:
e1 = Equation(L1, L2)

substitutions = OrderedDict(
# expect r = s = 0.5.
vsubs(P1, 0, -1, 0)...,
vsubs(P2, 2, 1, 0)...,
vsubs(P3, 0, 0, 0)...,
vsubs(P4, 2, 0, 0)...)

eq1s = substitute(e1, substitutions)
``````

from which I can solve in my head to r = s = 0.5.

How do I get `solve_for` to tell me that though?

``````solved = solve_for(eq1s, r)
``````

but `solved[1]` is

``````(1//0)*(2r - 2s)
``````

and `solved[2]`

``````(1//0)*(-1 + 2r)
``````

show division by zero.

What am I doing wrong?

How do I get `solve_for` to give me solutions?

Should I be doing something else instead?

1 Like

What is `variable` in

``````function symbolic_vector(name::Symbol, n::Integer)
eltname(name, i) = Symbol("(\$name)_\$i")
map(variable, map(i -> eltname(name, i), 1:n))
end
``````

`Symbolics.variable`. I must have forgot to include the "using"s. I’ll check for any more later when I’m at my computer.

Here’s a file that I’ve tested and is complete:

``````using DataStructures
using Symbolics
using Symbolics: variable, solve_for, substitute

"""
symbolic_vector(name::Symbol, n::Integer)

Define `n` Symbolics variables hose names are based on `name` and
return a vector of those variables.
"""
function symbolic_vector(name::Symbol, n::Integer)
eltname(name, i) = Symbol("(\$name)_\$i")
map(variable, map(i -> eltname(name, i), 1:n))
end

"""
vsubs(v::Vector{Symbolics.Num}, values...)

Return a list of `Pair`s suitable for constructing a `Dict` which is
suitable for passing to `Symbolics.substitute`, which
substitues each of `values` with the corresponding variable in `v`.
"""
function vsubs(v::Vector{Symbolics.Num}, values...)
Pair.(v, values)
end

"""
line(p1, p2, param)

Return the parametric formula for a point on a line which passes through points `p1` and `p2`, and has `param`.
"""
function line(p1, p2, param)
p1 + param * (p2 - p1)
end

P1 = symbolic_vector(:P1, 3)
P2 = symbolic_vector(:P2, 3)
P3 = symbolic_vector(:P3, 3)
P4 = symbolic_vector(:P4, 3)
@variables r, s
L1 = line(P1, P2, r)
L2 = line(P3, P4, s)
# L1 and L2 intersect at the point where their formulas are equal:
e1 = Equation(L1, L2)

substitutions = OrderedDict(
# expect r = s = 0.5.
vsubs(P1, 0, -1, 0)...,
vsubs(P2, 2, 1, 0)...,
vsubs(P3, 0, 0, 0)...,
vsubs(P4, 2, 0, 0)...)

eq1s = substitute(e1, substitutions)

solved = solve_for(eq1s, r)

println(solved)

``````

If I define

``````function vector_solve_for(e::Equation, var)
if e.lhs isa Vector && e.rhs isa Vector
result = []
for lr in zip(e.lhs, e.rhs)
push!(result,
solve_for(Equation(lr...), var))
end
result
else
solve_for(e, var)
end
end
``````

I can use it to get a value for `r`:

``````vector_solve_for(eq1s, r)
3-element Vector{Any}:
s
0.5
NaN
``````

but this doesn’t get me to automated solutions for both `r` and `s`.