# Занятие №3: эквивалентное сопротивление


```julia
using Base: hash, ==
using LinearAlgebra
```


```julia
"Тип данных для контакта, к которому подключаются сопротивления"
struct Pin
    value::Any
end

hash(x::Pin, h::UInt) = hash(x.value, h)
==(x::Pin, y::Pin) = x.value == y.value


"Пассивный элемент, т.е. сопротивление"
struct Passive{T <: Number}
    value::T
end


"Электрическая цепь из сопротивлений: множество контактов и отношение смежности между ними"
mutable struct Circuit{T <: Number}
    pins::Set{Pin}
    elements::Dict{Pin, Dict{Pin, Passive{T}}}
end

Circuit{T}() where T <: Number =
   Circuit(Set{Pin}(), Dict{Pin, Dict{Pin, Passive{T}}}())
```


```julia
"Добавить контакт в цепь"
function addpin!(circuit::Circuit{T}, a::Pin) where T <: Number
    if a in circuit.pins
        return false
    else
        push!(circuit.pins, a)
        circuit.elements[a] = Dict{Pin, Passive{T}}()
        return true
    end
end

"Добавить элемент в цепь и подключить к двум заданным контактам"
function addelement!(circuit::Circuit{T},
    element::Passive{T},
    a::Pin,
    b::Pin) where T <: Number
    
    addpin!(circuit, a)
    addpin!(circuit, b)

    circuit.elements[a][b] = element
    circuit.elements[b][a] = element
end

"Вывод уравнений для узловых потенциалов из правил Кирхгофа"
function equations(circuit::Circuit{T}) :: Tuple{Dict{Pin, Int},Matrix{T}} where T <: Number
    indices = Dict((p, i) for (i, p) in enumerate(circuit.pins))
    n = length(indices)
    
    equations = zeros(T, (n, n))
    for (p, pi) in pairs(indices)
        for (q, e) in circuit.elements[p]
            equations[pi, indices[q]] += 1 / e.value
            equations[pi, pi] -= 1 / e.value
        end
    end
    
    return (indices, equations)
end

"Найти эквивалентное сопротивление между двумя заданными узлами"
function equivalent(circuit::Circuit{T}, a::Pin, b::Pin) where T <: Number
    indices, eqs = equations(circuit)
    ia = indices[a]
    ib = indices[b]
    eqa = eqs[ia, :]

    eqs[ia, :] .= 0
    eqs[ia, ia] = 1

    eqs[ib, :] .= 0
    eqs[ib, ib] = 1
    
    rhs = zeros(T, length(indices))
    rhs[ib] = 1
    
    current = eqa ⋅ (eqs \ rhs)
    
    return 1 / current
end
```




    equivalent (generic function with 1 method)



# Примеры расчётов


```julia
circuit = Circuit{Float64}()
a = Pin("a")
b = Pin("b")
c = Pin("c")
addelement!(circuit, Passive(3.0), a, b)
addelement!(circuit, Passive(2.0), a, c)
addelement!(circuit, Passive(1.0), b, c)

equivalent(circuit, a, c)
```




    1.3333333333333333




```julia
circuit = Circuit{Rational{Int}}()
a = Pin("a")
b = Pin("b")
c = Pin("c")
addelement!(circuit, Passive(3//1), a, b)
addelement!(circuit, Passive(2//1), a, c)
addelement!(circuit, Passive(1//1), b, c)

equivalent(circuit, a, c)
```




    4//3




```julia
using Symbolics

@variables r_1 r_2 r_3

circuit = Circuit{Num}()
a = Pin("a")
b = Pin("b")
c = Pin("c")
addelement!(circuit, Passive(r_1), a, b)
addelement!(circuit, Passive(r_2), a, c)
addelement!(circuit, Passive(r_3), b, c)

equivalent(circuit, a, c)
```




\begin{equation}
\left( r_{2}^{-1} - \frac{1}{\left(  - \frac{1}{r_{1}} - \frac{1}{r_{3}} \right) r_{3} r_{1}} \right)^{-1}
\end{equation}




3cc3eeed37cfab0fd149a7b186583b7fd90e773b
ipynb
Jupyter Notebook
j03_resistors.ipynb
pydafe/judafe_logs_2021
230939d3631a4fcb67032142f8468bf1b066c3fd
MIT
j03_resistors.ipynb
pydafe/judafe_logs_2021
230939d3631a4fcb67032142f8468bf1b066c3fd
MIT
j03_resistors.ipynb
pydafe/judafe_logs_2021
230939d3631a4fcb67032142f8468bf1b066c3fd
MIT
2021-12-15T18:04:09.000Z
2021-12-15T18:04:09.000Z
Qwen/Qwen-72B
1. YES
2. YES