Reference
JosephsonCircuits.Phi0
— Constantconst Phi0
A constant for Phi0, the magnetic flux quantum in Weber, HA: Phi0 = h/(2charge of electron).
JosephsonCircuits.phi0
— Constantconst phi0
A constant for phi0, the reduced magnetic flux quantum in Weber, HA: phi0 = hbar/(2charge of electron).
JosephsonCircuits.speed_of_light
— Constantconst speed_of_light
A constant for the speed of light which is 2.99792458e8 m/s
JosephsonCircuits.CircuitGraph
— TypeCircuitGraph(edge2indexdict, Rbn, searray, cearray, glearray, lvarray,
isolatednodes, gl, Nbranches)
A simple structure to hold the circuit graph information.
JosephsonCircuits.CircuitMatrices
— TypeCircuitMatrices(Cnm::SparseMatrixCSC, Gnm::SparseMatrixCSC, Lb::SparseVector
Lbm::SparseVector, Ljb::SparseVector, Ljbm::SparseVector,
Mb::SparseMatrixCSC, invLnm::SparseMatrixCSC,
Rbnm::SparseMatrixCSC{Int, Int}, portindices::Vector{Int},
portnumbers::Vector{Int}, portimpedanceindices::Vector{Int}
noiseportimpedanceindices::Vector{Int}, Lmean, vvn)
A simple structure to hold the circuit matrices including the capacitance matrix, the conductance matrix, the inductance vectors, the Josephson inductance vectors, the mutual inductance matrix, the inverse inductance matrix, the incidence matrix, the dictionary of port and resistor values where the nodes are the keys and the values are the values, and the mean of the inductances. See also numericmatrices
and symbolicmatrices
.
Fields
Cnm::SparseMatrixCSC
: the capacitance matrix in the node basis with each element duplicated along the diagonal Nmodes times.Gnm::SparseMatrixCSC
: the conductance matrix in the node basis with each element duplicated along the diagonal Nmodes times.Lb::SparseVector
: vector of branch linear inductances.Lbm::SparseVector
: vector of branch linear inductances with each element duplicated Nmodes times.Ljb::SparseVector
: vector of branch Josephson junction inductances.Ljbm::SparseVector
: vector of branch Josephson junction inductances with each element duplicated Nmodes times.Mb::SparseMatrixCSC
: the mutual inductance matrix in the branch basis with each element duplicated along the diagonal Nmodes times.invLnm::SparseMatrixCSC
: the inverse inductance matrix in the node basis with each element duplicated along the diagonal Nmodes times.Rbnm::SparseMatrixCSC{Int, Int}
: incidence matrix to convert between the node and branch bases.portindices::Vector{Int}
: vector of indices at which ports occur.portnumbers::Vector{Int}
: vector of port numbers.portimpedanceindices::Vector{Int}
: vector of indices at which port impedances occur.noiseportimpedanceindices::Vector{Int}
: vector of indices at which resistive elements other than port impedances occur, for noise calculations.Lmean
: the mean of all of the geometric and Josephson inductances.vvn
: the vector of component values with numbers substituted in.
JosephsonCircuits.CoupledLinesBasis
— TypeCoupledLinesBasis(ZC, TI, TV, theta, U, lambda, S)
A simple structure to hold the output of ZC_basis_coupled_tlines
.
JosephsonCircuits.Factorization
— TypeFactorization(outofplace,inplace,kwargs)
A structure to hold the factorizations and their keyword arguments.
```
JosephsonCircuits.FactorizationCache
— TypeFactorizationCache(factorization)
A cache for the factorization object.
Examples
julia> JosephsonCircuits.FactorizationCache(JosephsonCircuits.KLU.klu(JosephsonCircuits.sparse([1, 2], [1, 2], [1/2, 1/2], 2, 2)));
JosephsonCircuits.FourierIndices
— TypeFourierIndices(conjsymdict::Dict{CartesianIndex{N},CartesianIndex{N}},
vectomatmap::Vector{Int}, conjsourceindices::Vector{Int},
conjtargetindices::Vector{Int}, hbmatmodes::Matrix{NTuple{N, Int}},
hbmatindices::Matrix{Int})
A simple structure to hold time and frequency domain information for the signals, particularly the indices for converting between the node flux vectors and matrices. See also fourierindices
.
JosephsonCircuits.Frequencies
— TypeFrequencies(Nharmonics::NTuple{N, Int}, Nw::NTuple{N,Int}, Nt::NTuple{N,Int},
coords::Vector{CartesianIndex{N}}, modes::Vector{NTuple{N,Int})
A simple structure to hold time and frequency domain information for the signals. See also calcfreqsrdft
and calcfreqsdft
.
Fields
Nharmonics::NTuple{N, Int}
: The number of harmonics for each frequency.Nw::NTuple{N,Int}
: The dimensions of the frequency domain signal for a single node.Nt::NTuple{N,Int}
: The dimensions of the time domain signal for a single node.coords::Vector{CartesianIndex{N}}
: The coordinates of each mixing products.modes::Vector{NTuple{N,Int}}
: The mode indices of each mixing product, eg. (0,0), (1,0), (2,1).
Examples
Nharmonics = (2,1)
Nw = (3, 3)
Nt = (4, 3)
coords = CartesianIndex{2}[CartesianIndex(1, 1), CartesianIndex(2, 1), CartesianIndex(3, 1), CartesianIndex(1, 2), CartesianIndex(2, 2), CartesianIndex(3, 2), CartesianIndex(1, 3), CartesianIndex(2, 3), CartesianIndex(3, 3)]
modes = [(0, 0), (1, 0), (2, 0), (0, 1), (1, 1), (2, 1), (0, -1), (1, -1), (2, -1)]
JosephsonCircuits.Frequencies(Nharmonics, Nw,Nt,coords,modes)
# output
JosephsonCircuits.Frequencies{2}((2, 1), (3, 3), (4, 3), CartesianIndex{2}[CartesianIndex(1, 1), CartesianIndex(2, 1), CartesianIndex(3, 1), CartesianIndex(1, 2), CartesianIndex(2, 2), CartesianIndex(3, 2), CartesianIndex(1, 3), CartesianIndex(2, 3), CartesianIndex(3, 3)], [(0, 0), (1, 0), (2, 0), (0, 1), (1, 1), (2, 1), (0, -1), (1, -1), (2, -1)])
JosephsonCircuits.HB
— TypeHB(nonlinear, linearized)
A simple structure to hold the nonlinear and linearized harmonic balance solutions.
Fields
nonlinear
: nonlinear harmonic balance solution for pump and pump harmonics. SeeNonlinearHB
.linearized
: linearized harmonic balance solution. SeeLinearizedHB
.
JosephsonCircuits.LinearizedHB
— TypeLinearizedHB(S, Snoise, QE, QEideal, CM, nodeflux, voltage, Nmodes, Nnodes,
Nbranches, signalindex, w)
A simple structure to hold the linearized harmonic balance solutions.
Fields
w
: the signal frequencies.modes
: tuple of the signal mode indices where (0,) is the signal.S
: the scattering matrix relating inputs and outputs for each combination of port and frequency.Snoise
: the scattering matrix relating inputs at the noise ports. (lossy devices) and outputs at the physical ports for each combination of port and frequency.Ssensitivity
:Z
:Zadjoint
:Zsensitivity
:Zsensitivityadjoint
:QE
: the quantum efficiency for each combination of port and frequency.QEideal
: the quantum efficiency for an ideal amplifier with the same level of gain, for each combination of port and frequency.CM
: the commutation relations (equal to ±1), for each combination of port and frequency.nodeflux
: the node fluxes resulting from inputs at each frequency and port.nodefluxadjoint
: the node fluxes resulting from inputs at each frequency and port with a time reversed modulation.voltage
: the node voltages resulting from inputs at each frequency and port.voltageadjoint
: the node fluxes resulting from inputs at each frequency and port with a time reversed modulation.nodenames
: the vector of unique node strings.nodeindices
:componentnames
:componenttypes
:componentnamedict
:mutualinductorbranchnames
:portnumbers
: vector of port numbers.portindices
:portimpedanceindices
:noiseportimpedanceindices
:sensitivitynames
:sensitivityindices
:Nmodes
: the number of signal and idler frequencies.Nnodes
: the number of nodes in the circuit (including the ground node).Nbranches
: the number of branches in the circuit.Nports
: the number of ports.signalindex
: the index of the signal mode.
JosephsonCircuits.NonlinearHB
— TypeNonlinearHB(nodeflux, Rbnm, Ljb, Lb, Ljbm, Nmodes, Nbranches, S)
A simple structure to hold the nonlinear harmonic balance solutions.
Fields
w
: a tuple containing the the angular frequency of the pump in radians/s.frequencies
:nodeflux
: the node fluxes resulting from inputs at each frequency and port.Rbnm
: incidence matrix to convert between the node and branch basis.Ljb
: sparse vector of Josephson junction inductances.Lb
: sparse vector of linear inductances.Ljbm
: sparse vector of linear inductances with each element duplicated Nmodes times.Nmodes
: the number of signal and idler frequencies.Nbranches
: the number of branches in the circuit.nodenames
: the vector of unique node name strings.componentnames
: the vector of component name stringsportnumbers
: vector of port numbers.portindices
:modes
: tuple of the pump mode indices where (1,) is the pump in the single pump case.S
: the scattering matrix relating inputs and outputs for each combination of port and frequency.
JosephsonCircuits.ParsedCircuit
— TypeParsedCircuit(nodeindexvector::Vector{Int},
uniquenodevector::Vector{String},
mutualinductorbranchnames::Vector{String},
componentnames::Vector{String}, componenttypes::Vector{Symbol},
componentvalues::Vector, componentnamedict::Dict{String, Int},
Nnodes::Int)
A simple structure to hold the parsed circuit including a vector of node indices, the unique node names, the inductors coupled by the mutual inductors, the component names, the component types, the values of the components, a dictionary of the names of the components as keys and the index at which the component occurs as the value, and dictionaries for the ports and resistors where the pair of nodes is the key and value is the component value.
See also parsecircuit
.
Fields
nodeindexvector::Vector{Int}
: sorted vector of node indices where the two nodes for each component occur as consecutive elements (pairs).uniquenodevector::Vector{String}
: the unique node names.mutualinductorbranchnames::Vector{String}
: the inductors coupled by the mutual inductors.componentnames::Vector{String}
: component names.componenttypes::Vector{Symbol}
: the component (electrical engineering) types.componentvalues::Vector
: the component values.componentnamedict::Dict{String, Int}
: names of the components as keys and the index at which the component occurs as the value.Nnodes::Int
: number of nodes including the ground node.
Examples
@variables Ipump Rleft L1 K1 L2 C2
println(JosephsonCircuits.ParsedCircuit(
[1, 2, 1, 2, 1, 2, 1, 2, 0, 0, 3, 2, 3, 2],
["1", "0", "2"], ["L1", "L2"],
["P1", "I1", "R1", "L1", "K1", "L2", "C2"],
[:P, :I, :R, :L, :K, :L, :C],
Num[1, Ipump, Rleft, L1, K1, L2, C2],
Dict("L1" => 4, "I1" => 2, "L2" => 6, "C2" => 7, "R1" => 3, "P1" => 1, "K1" => 5),
3))
# output
JosephsonCircuits.ParsedCircuit([1, 2, 1, 2, 1, 2, 1, 2, 0, 0, 3, 2, 3, 2], ["1", "0", "2"], ["L1", "L2"], ["P1", "I1", "R1", "L1", "K1", "L2", "C2"], [:P, :I, :R, :L, :K, :L, :C], Num[1, Ipump, Rleft, L1, K1, L2, C2], Dict("L1" => 4, "I1" => 2, "L2" => 6, "C2" => 7, "R1" => 3, "P1" => 1, "K1" => 5), 3)
JosephsonCircuits.ParsedSortedCircuit
— TypeParsedSortedCircuit(nodeindices::Matrix{Int},
nodenames::Vector{String},
mutualinductorbranchnames::Vector{String},
componentnames::Vector{String},
componenttypes::Vector{Symbol}, componentvalues::Vector,
componentnamedict::Dict{String, Int}, Nnodes::Int)
A simple structure to hold the parsed and sorted circuit. See also parsesortcircuit
, parsecircuit
, and sortnodes
for more explanation.
Fields
nodeindices::Matrix{Int}
: sorted array of node indices (where the length of the first axis is 2).nodenames::Vector{String}
: the sorted unique node names.mutualinductorbranchnames::Vector{String}
: the inductors coupled by the mutual inductors.componentnames::Vector{String}
: component names.componenttypes::Vector{Symbol}
: the component (electrical engineering) types.componentvalues::Vector
: the component values.componentnamedict::Dict{String, Int}
: names of the components as keys and the index at which the component occurs as the value.Nnodes::Int
: number of nodes including the ground node.
Examples
@variables Ipump Rleft L1 K1 L2 C2
println(JosephsonCircuits.ParsedSortedCircuit(
[2 2 2 2 0 3 3; 1 1 1 1 0 1 1],
["0", "1", "2"],
["L1", "L2"],
["P1", "I1", "R1", "L1", "K1", "L2", "C2"],
[:P, :I, :R, :L, :K, :L, :C],
Num[1, Ipump, Rleft, L1, K1, L2, C2],
Dict("L1" => 4, "I1" => 2, "L2" => 6, "C2" => 7, "R1" => 3, "P1" => 1, "K1" => 5),
3))
# output
JosephsonCircuits.ParsedSortedCircuit([2 2 2 2 0 3 3; 1 1 1 1 0 1 1], ["0", "1", "2"], ["L1", "L2"], ["P1", "I1", "R1", "L1", "K1", "L2", "C2"], [:P, :I, :R, :L, :K, :L, :C], Num[1, Ipump, Rleft, L1, K1, L2, C2], Dict("L1" => 4, "I1" => 2, "L2" => 6, "C2" => 7, "R1" => 3, "P1" => 1, "K1" => 5), 3)
JosephsonCircuits.SpiceRaw
— TypeSpiceRaw(header::SpiceRawHeader, variables::Dict{String, Vector{String}},
values::Dict{String,T})
A simple structure to hold the SPICE raw file contents including the header, variables, and values.
Examples
julia> JosephsonCircuits.SpiceRaw{Matrix{ComplexF64}}(JosephsonCircuits.SpiceRawHeader("CKT1", "Thu Dec 29 01:29:27 2022", "A.C. Small signal analysis", "complex", 4, 3, "version 4.3.14", ""), Dict("V" => ["v(1)", "v(2)", "v(3)"], "Hz" => ["frequency"]), Dict{String, Matrix{ComplexF64}}("V" => [48.87562301047733 - 7.413126995337487im 49.97131616467212 + 1.1949290155299537im 49.02611690128596 - 6.90980805243651im; -10.116167243319213 + 1.534380793728424im 57.578470543293086 + 1.3775359827006193im 12.368446655904192 - 1.743197747303436im; 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im], "Hz" => [4.0e9 + 0.0im 5.0e9 + 0.0im 6.0e9 + 0.0im]))
JosephsonCircuits.SpiceRaw{Matrix{ComplexF64}}(JosephsonCircuits.SpiceRawHeader("CKT1", "Thu Dec 29 01:29:27 2022", "A.C. Small signal analysis", "complex", 4, 3, "version 4.3.14", ""), Dict("V" => ["v(1)", "v(2)", "v(3)"], "Hz" => ["frequency"]), Dict{String, Matrix{ComplexF64}}("V" => [48.87562301047733 - 7.413126995337487im 49.97131616467212 + 1.1949290155299537im 49.02611690128596 - 6.90980805243651im; -10.116167243319213 + 1.534380793728424im 57.578470543293086 + 1.3775359827006193im 12.368446655904192 - 1.743197747303436im; 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im], "Hz" => [4.0e9 + 0.0im 5.0e9 + 0.0im 6.0e9 + 0.0im]))
JosephsonCircuits.SpiceRawHeader
— TypeSpiceRawHeader(title::String, date::String, plotname::String,
flags::String, nvariables::Int, npoints::Int, command::String,
option::String)
A simple structure to hold the SPICE raw file header.
Examples
julia> JosephsonCircuits.SpiceRawHeader("CKT1", "Thu Dec 29 01:29:27 2022", "A.C. Small signal analysis", "complex", 4, 3, "version 4.3.14", "")
JosephsonCircuits.SpiceRawHeader("CKT1", "Thu Dec 29 01:29:27 2022", "A.C. Small signal analysis", "complex", 4, 3, "version 4.3.14", "")
JosephsonCircuits.TouchstoneFile
— TypeTouchstoneFile(f::Vector{Float64},
N::Array{Complex{Float64}},
frequencyunit::String,
parameter::String,
format::String,
R::Float64,
version::Float64,
numberofports::Int,
twoportdataorder::String,
numberoffrequencies::Int,
numberofnoisefrequencies::Int,
reference::Vector{Float64},
information::Vector{String},
matrixformat::String,
mixedmodeorder::Vector{Tuple{Char, Vector{Int}}},
comments::Vector{String},
networkdata::Vector{Float64},
noisedata::Vector{Float64})
A structure to hold the data contained in a Touchstone file. In most cases, the user will not generate the struct directly. Instead, they will load a Touchstone file with touchstone_load
, parse an IOStream or IOBuffer with touchstone_parse
, or generate a TouchstoneFile struct with touchstone_file
.
JosephsonCircuits.ABCD_PiY!
— MethodABCD_PiY!(ABCD,Y1,Y2,Y3)
In-place version of ABCD_PiY
.
Examples
julia> JosephsonCircuits.ABCD_PiY!(zeros(Complex{Float64},2,2),1,2,4)
2×2 Matrix{ComplexF64}:
1.5+0.0im 0.25+0.0im
3.5+0.0im 1.25+0.0im
JosephsonCircuits.ABCD_PiY
— MethodABCD_PiY(Y1,Y2,Y3)
Return the ABCD matrix for a Pi network of admittances Y1
, Y2
, and Y3
.
o----Y3-----o
| |
Y1 Y2
| |
o-----------o
Examples
julia> JosephsonCircuits.ABCD_PiY(1.0+0.0im,2.0+0.0im,4.0+0.0im)
2×2 Matrix{ComplexF64}:
1.5+0.0im 0.25-0.0im
3.5+0.0im 1.25+0.0im
JosephsonCircuits.ABCD_TZ!
— MethodABCD_TZ!(ABCD,Z1,Z2,Z3)
In-place version of ABCD_TZ
.
Examples
julia> JosephsonCircuits.ABCD_TZ!(ones(Complex{Float64},2,2),1,2,4)
2×2 Matrix{ComplexF64}:
1.25+0.0im 3.5+0.0im
0.25+0.0im 1.5+0.0im
JosephsonCircuits.ABCD_TZ
— MethodABCD_TZ(Z1,Z2,Z3)
Return the ABCD matrix for a T network of impedances Z1
, Z2
, and Z3
.
o--Z1-----Z2--o
|
Z3
|
o-------------o
Examples
julia> JosephsonCircuits.ABCD_TZ(1.0+0.0im,2.0+0.0im,4.0+0.0im)
2×2 Matrix{ComplexF64}:
1.25+0.0im 3.5+0.0im
0.25-0.0im 1.5+0.0im
JosephsonCircuits.ABCD_coupled_tline!
— MethodABCD_coupled_tline!(A, Z0e, Z0o, thetae, thetao)
In-place version of ABCD_coupled_tline
.
Examples
julia> JosephsonCircuits.ABCD_coupled_tline!(zeros(Complex{Float64},4,4),50,50,pi/4,pi/4)
4×4 Matrix{ComplexF64}:
0.707107+0.0im 0.0+0.0im … 0.0+0.0im
0.0+0.0im 0.707107+0.0im 0.0+35.3553im
0.0+0.0141421im 0.0+0.0im 0.0+0.0im
0.0+0.0im 0.0+0.0141421im 0.707107+0.0im
JosephsonCircuits.ABCD_coupled_tline
— MethodABCD_coupled_tline(Z0e, Z0o, thetae, thetao)
Return the ABCD matrix for two coupled transmission lines described by even and odd mode phase delays thetae
and thetao
, and even and odd mode impedances Z0e
and Z0o
.
thetae, Z0e
thetao, Z0o
V1, I1 --> ======== <-- I3, V3
V2, I2 --> ======== <-- I4, V4
[(V1+V2)/2, (I1+I2)/2] = ABCDe * [(V3+V4)/2, -(I3+I4)/2]
[(V1-V2)/2, (I1-I2)/2] = ABCDo * [(V3-V4)/2, -(I3-I4)/2]
[V1, V2, I1, I2] = ABCD_coupled_tline * [V3, V4, -I3, -I4]
Examples
julia> JosephsonCircuits.ABCD_coupled_tline(50,50,pi/4,pi/4)
4×4 Matrix{ComplexF64}:
0.707107+0.0im 0.0+0.0im … 0.0+0.0im
0.0+0.0im 0.707107+0.0im 0.0+35.3553im
0.0+0.0141421im 0.0+0.0im 0.0+0.0im
0.0+0.0im 0.0+0.0141421im 0.707107+0.0im
JosephsonCircuits.ABCD_seriesZ!
— MethodABCD_seriesZ!(ABCD,Z1)
In-place version of ABCD_seriesZ
.
Examples
julia> JosephsonCircuits.ABCD_seriesZ!(zeros(Complex{Float64},2,2),50)
2×2 Matrix{ComplexF64}:
1.0+0.0im 50.0+0.0im
0.0+0.0im 1.0+0.0im
JosephsonCircuits.ABCD_seriesZ
— MethodABCD_seriesZ(Z1)
Return the ABCD matrix for a series impedance Z1
.
o---Z1---o
o--------o
Examples
julia> JosephsonCircuits.ABCD_seriesZ(50.0+0.0im)
2×2 Matrix{ComplexF64}:
1.0+0.0im 50.0+0.0im
0.0+0.0im 1.0+0.0im
JosephsonCircuits.ABCD_shuntY!
— MethodABCD_shuntY!(ABCD,Y1)
In-place version of ABCD_shuntY
.
Examples
julia> JosephsonCircuits.ABCD_shuntY!(zeros(Complex{Float64},2,2),1/50)
2×2 Matrix{ComplexF64}:
1.0+0.0im 0.0+0.0im
0.02+0.0im 1.0+0.0im
JosephsonCircuits.ABCD_shuntY
— MethodABCD_shuntY(Y1)
Return the ABCD matrix for a shunt admittance Y1
.
o---------o
|
Y1
|
o---------o
Examples
julia> JosephsonCircuits.ABCD_shuntY(1/(50.0+0.0im))
2×2 Matrix{ComplexF64}:
1.0+0.0im 0.0+0.0im
0.02-0.0im 1.0+0.0im
JosephsonCircuits.ABCD_tline!
— MethodABCD_tline!(ABCD, Z0, theta)
In-place version of ABCD_tline
.
Examples
julia> JosephsonCircuits.ABCD_tline!(ones(Complex{Float64},2,2),50, pi/4)
2×2 Matrix{ComplexF64}:
0.707107+0.0im 0.0+35.3553im
0.0+0.0141421im 0.707107+0.0im
JosephsonCircuits.ABCD_tline
— MethodABCD_tline(Z0, theta)
Return the ABCD matrix for a transmission line described by phase delay theta
in radians and characteristic impedance Z0
in Ohms.
theta, Z0
o--========--o
o------------o
Examples
julia> JosephsonCircuits.ABCD_tline(50, pi/4)
2×2 Matrix{ComplexF64}:
0.707107+0.0im 0.0+35.3553im
0.0+0.0141421im 0.707107+0.0im
JosephsonCircuits.ABCDtoS
— FunctionABCDtoS(ABCD;portimpedances=50.0)
Convert the 2 port chain (ABCD) matrix ABCD
to the scattering parameter matrix S
and return the result. Assumes a port impedance of 50 Ohms unless specified with the portimpedances
keyword argument.
References
Russer, Peter. Electromagnetics, Microwave Circuit, And Antenna Design for Communications Engineering, Second Edition. Artech House, 2006.
JosephsonCircuits.A_coupled_tlines
— MethodA_coupled_tlines(L,Cmaxwell,l,omega)
Returns the 2mx2m chain (ABCD) matrix for a port number symmetric multi-port network of m coupled transmission lines described by a symmetric mxm Maxwell inductance (per unit length) matrix L
, a symmetric mxm Maxwell capacitance matrix (per unit length) Cmaxwell
, a physical length l
, and an angular frequency omega
.
V_1, I_1 --> ======== <-- I_{m+1}, V_{m+1}
V_2, I_2 --> ======== <-- I_{m+2}, V_{m+2}
.
.
.
V_m, I_m --> ======== <-- I_n, V_n
<---l-->
where n=2*m.
[V_1, ...V_m, I_1, ...I_m] = A_coupled_tline * [V_{m+1}, ...V_n, I_{m+1}, ...I_n]
Examples
Zeven = 51.0
Zodd = 49.0
neven = 1.1
nodd = 1.08
l = 3.5e-3
c = JosephsonCircuits.speed_of_light
omega = 2*pi*5e9
L, C = JosephsonCircuits.even_odd_to_maxwell(Zeven, Zodd, neven, nodd)
A1 = JosephsonCircuits.A_coupled_tlines(L,C,l,omega)
A2 = JosephsonCircuits.ABCD_coupled_tline(Zeven,Zodd,neven*omega/c*l,nodd*omega/c*l)
println(isapprox(A1,A2))
# output
true
References
Paul, Clayton R. Analysis of Multiconductor Transmission Lines, Second Edition. Wiley, 2008.
JosephsonCircuits.AtoB
— FunctionAtoB(A)
Convert the chain (ABCD) matrix A
to the inverse chain matrix B
and return the result. Note that despite the name, the inverse of the chain matrix is not equal to the inverse chain matrix, inv(A) ≠ B.
Examples
julia> A = Complex{Float64}[1.0 0.0;1/50 1.0];JosephsonCircuits.AtoB(A)
2×2 Matrix{ComplexF64}:
1.0+0.0im 0.0+0.0im
0.02-0.0im 1.0-0.0im
References
Russer, Peter. Electromagnetics, Microwave Circuit, And Antenna Design for Communications Engineering, Second Edition. Artech House, 2006.
JosephsonCircuits.AtoB!
— MethodAtoB!(B::AbstractMatrix,A::AbstractMatrix,tmp::AbstractMatrix)
See AtoB
for description.
JosephsonCircuits.AtoS
— FunctionAtoS(A)
Convert the chain (ABCD) matrix A
to the scattering parameter matrix S
and return the result.
References
Russer, Peter. Electromagnetics, Microwave Circuit, And Antenna Design for Communications Engineering, Second Edition. Artech House, 2006.
JosephsonCircuits.AtoS!
— MethodAtoS!(S::AbstractMatrix, A::AbstractMatrix, tmp::AbstractMatrix,
sqrtportimpedances1, sqrtportimpedances2)
See AtoS
for description.
JosephsonCircuits.AtoY
— FunctionAtoY(A)
Convert the chain (ABCD) matrix A
to the admittance matrix Y
and return the result.
Examples
julia> A = Complex{Float64}[-1 -50.0;0 -1];JosephsonCircuits.AtoY(A)
2×2 Matrix{ComplexF64}:
0.02+0.0im 0.02+0.0im
0.02+0.0im 0.02+0.0im
References
Russer, Peter. Electromagnetics, Microwave Circuit, And Antenna Design for Communications Engineering, Second Edition. Artech House, 2006.
JosephsonCircuits.AtoY!
— MethodAtoY!(Y::AbstractMatrix,A::AbstractMatrix,tmp::AbstractMatrix)
See AtoY
for description.
JosephsonCircuits.AtoZ
— FunctionAtoZ(A)
Convert the ABCD matrix A
to the impedance matrix Z
and return the result.
Examples
julia> A = Complex{Float64}[1.0 0.0;1/50 1.0];JosephsonCircuits.AtoZ(A)
2×2 Matrix{ComplexF64}:
50.0+0.0im 50.0+0.0im
50.0+0.0im 50.0+0.0im
References
Russer, Peter. Electromagnetics, Microwave Circuit, And Antenna Design for Communications Engineering, Second Edition. Artech House, 2006.
JosephsonCircuits.AtoZ!
— MethodAtoZ!(Z::AbstractMatrix,A::AbstractMatrix,tmp::AbstractMatrix)
See AtoZ
for description.
JosephsonCircuits.BtoA
— FunctionBtoA(B)
Convert the inverse chain matrix B
to the chain (ABCD) matrix A
and return the result. Note that despite the name, the inverse of the chain matrix is not equal to the inverse chain matrix, inv(A) ≠ B.
Examples
julia> B = Complex{Float64}[1.0 0.0;1/50 1.0];JosephsonCircuits.BtoA(B)
2×2 Matrix{ComplexF64}:
1.0+0.0im 0.0+0.0im
0.02-0.0im 1.0-0.0im
References
Russer, Peter. Electromagnetics, Microwave Circuit, And Antenna Design for Communications Engineering, Second Edition. Artech House, 2006.
JosephsonCircuits.BtoA!
— MethodBtoA!(A::AbstractMatrix,B::AbstractMatrix,tmp::AbstractMatrix)
See BtoA
for description.
JosephsonCircuits.BtoS
— FunctionBtoS(B)
Convert the inverse chain (ABCD) matrix B
to the scattering parameter matrix S
and return the result.
References
Russer, Peter. Electromagnetics, Microwave Circuit, And Antenna Design for Communications Engineering, Second Edition. Artech House, 2006 with change of overall sign (suspected typo).
JosephsonCircuits.BtoS!
— MethodBtoS!(S::AbstractMatrix, B::AbstractMatrix, tmp::AbstractMatrix,
sqrtportimpedances1, sqrtportimpedances2)
See BtoS
for description.
JosephsonCircuits.BtoY
— FunctionBtoY(A)
Convert the inverse chain matrix B
to the admittance matrix Y
and return the result.
Examples
julia> B = Complex{Float64}[-1 -50.0;0 -1];JosephsonCircuits.BtoY(B)
2×2 Matrix{ComplexF64}:
0.02+0.0im 0.02+0.0im
0.02+0.0im 0.02+0.0im
References
Russer, Peter. Electromagnetics, Microwave Circuit, And Antenna Design for Communications Engineering, Second Edition. Artech House, 2006.
JosephsonCircuits.BtoY!
— MethodBtoY!(Y::AbstractMatrix,B::AbstractMatrix,tmp::AbstractMatrix)
See BtoY
for description.
JosephsonCircuits.BtoZ
— FunctionBtoZ(A)
Convert the inverse chain matrix B
to the impedance matrix Z
and return the result.
Examples
julia> B = Complex{Float64}[1.0 0.0;1/50 1];JosephsonCircuits.BtoZ(B)
2×2 Matrix{ComplexF64}:
50.0+0.0im 50.0+0.0im
50.0+0.0im 50.0+0.0im
References
Russer, Peter. Electromagnetics, Microwave Circuit, And Antenna Design for Communications Engineering, Second Edition. Artech House, 2006 with change of sign on B21 and B22 terms (suspected typo).
JosephsonCircuits.BtoZ!
— MethodBtoZ!(Z::AbstractMatrix,B::AbstractMatrix,tmp::AbstractMatrix)
See BtoZ
for description.
JosephsonCircuits.CMtokeyed
— MethodCMtokeyed(CM, outputmodes, outputportnumbers, w)
Convert a commutation relation array CM
vs frequency w
to a keyed array. Return the keyed array.
Examples
julia> JosephsonCircuits.CMtokeyed([1 2;3 4;;;],[(0,)],[1,2],[1.0,1.1])
3-dimensional KeyedArray(NamedDimsArray(...)) with keys:
↓ outputmode ∈ 1-element Vector{Tuple{Int64}}
→ outputport ∈ 2-element Vector{Int64}
◪ freqindex ∈ 2-element UnitRange{Int64}
And data, 1×2×2 Array{Int64, 3}:
[:, :, 1] ~ (:, :, 1):
(1) (2)
(0,) 1 3
[:, :, 2] ~ (:, :, 2):
(1) (2)
(0,) 2 4
JosephsonCircuits.IctoLj
— MethodIctoLj(Ic)
Convert the junction critical current to inductance in SI base units.
Examples
julia> IctoLj(3.29105976e-6)
1.0e-10
JosephsonCircuits.LjtoIc
— MethodLjtoIc(Lj)
Convert the junction inductance to critical current in SI base units.
Examples
julia> LjtoIc(100e-12)
3.29105976e-6
JosephsonCircuits.S_match!
— MethodS_match!(S::AbstractArray)
Return the scattering parameters for a N port ideal match. OverwriteS
with the output.
Examples
julia> JosephsonCircuits.S_match!(ones(1,1))
1×1 Matrix{Float64}:
0.0
julia> JosephsonCircuits.S_match!(ones(1,1,2))
1×1×2 Array{Float64, 3}:
[:, :, 1] =
0.0
[:, :, 2] =
0.0
JosephsonCircuits.S_open!
— MethodS_open!(S::AbstractArray)
Return the scattering parameters for a N port ideal open. OverwriteS
with the output.
Examples
julia> JosephsonCircuits.S_open!(ones(1,1))
1×1 Matrix{Float64}:
1.0
julia> JosephsonCircuits.S_open!(ones(2,2))
2×2 Matrix{Float64}:
1.0 0.0
0.0 1.0
JosephsonCircuits.S_short!
— MethodS_short!(S::AbstractArray)
Return the scattering parameters for a N port ideal short. OverwriteS
with the output.
Examples
julia> JosephsonCircuits.S_short!(ones(1,1))
1×1 Matrix{Float64}:
-1.0
julia> JosephsonCircuits.S_short!(ones(2,2))
2×2 Matrix{Float64}:
-1.0 0.0
0.0 -1.0
JosephsonCircuits.S_splitter!
— MethodS_splitter!(S::AbstractArray)
Return the scattering parameters for a N port ideal lossless symmetrical reciprocal network. Overwrite S
with the output.
Examples
julia> JosephsonCircuits.S_splitter!(ones(2,2))
2×2 Matrix{Float64}:
0.0 1.0
1.0 0.0
julia> JosephsonCircuits.S_splitter!(ones(3,3))
3×3 Matrix{Float64}:
-0.333333 0.666667 0.666667
0.666667 -0.333333 0.666667
0.666667 0.666667 -0.333333
JosephsonCircuits.Snoisetokeyed
— MethodSnoisetokeyed(Snoise, inputmodes, components, outputmodes,
outputportnumbers, w)
Convert a noise scattering parameter array Snoise
vs frequency w
to a keyed array. Return the keyed array.
Examples
julia> JosephsonCircuits.Snoisetokeyed([11 12;21 22;;;],[(0,)],["C1","C2"],[(0,)],[1,2],[1.0])
5-dimensional KeyedArray(NamedDimsArray(...)) with keys:
↓ inputmode ∈ 1-element Vector{Tuple{Int64}}
→ component ∈ 2-element Vector{String}
◪ outputmode ∈ 1-element Vector{Tuple{Int64}}
▨ outputport ∈ 2-element Vector{Int64}
▨ freqindex ∈ 1-element UnitRange{Int64}
And data, 1×2×1×2×1 Array{Int64, 5}:
[:, :, 1, 1, 1] ~ (:, :, (0,), 1, 1):
("C1") ("C2")
(0,) 11 21
[:, :, 1, 2, 1] ~ (:, :, (0,), 2, 1):
("C1") ("C2")
(0,) 12 22
JosephsonCircuits.StoA
— FunctionStoA(S)
Convert the scattering parameter matrix S
to the chain (ABCD) matrix A
and return the result.
References
Russer, Peter. Electromagnetics, Microwave Circuit, And Antenna Design for Communications Engineering, Second Edition. Artech House, 2006.
JosephsonCircuits.StoA!
— MethodStoA!(A::AbstractMatrix, S::AbstractMatrix, tmp::AbstractMatrix,
sqrtportimpedances1, sqrtportimpedances2)
See StoA
for description.
JosephsonCircuits.StoABCD
— FunctionStoABCD(S;portimpedances=50.0))
Convert the scattering parameter matrix S
to the 2 port chain (ABCD) matrix and return the result. Assumes a port impedance of 50 Ohms unless specified with the portimpedances
keyword argument.
References
Russer, Peter. Electromagnetics, Microwave Circuit, And Antenna Design for Communications Engineering, Second Edition. Artech House, 2006.
JosephsonCircuits.StoB
— FunctionStoB(S)
Convert the scattering parameter matrix S
to the inverse chain (ABCD) matrix B
and return the result. Note that despite the name, the inverse of the chain matrix is not equal to the inverse chain matrix, inv(A) ≠ B.
References
Russer, Peter. Electromagnetics, Microwave Circuit, And Antenna Design for Communications Engineering, Second Edition. Artech House, 2006.
JosephsonCircuits.StoB!
— MethodStoB!(B::AbstractMatrix, S::AbstractMatrix, tmp::AbstractMatrix,
sqrtportimpedances1, sqrtportimpedances2)
See StoB
for description.
JosephsonCircuits.StoT
— FunctionStoT(S)
Convert the scattering parameter matrix S
to a transmission matrix T
and return the result.
Examples
julia> S = Complex{Float64}[0.0 1.0;1.0 0.0];JosephsonCircuits.StoT(S)
2×2 Matrix{ComplexF64}:
1.0+0.0im -0.0+0.0im
-0.0-0.0im 1.0-0.0im
References
Russer, Peter. Electromagnetics, Microwave Circuit, And Antenna Design for Communications Engineering, Second Edition. Artech House, 2006.
JosephsonCircuits.StoT!
— MethodStoT!(T::AbstractMatrix,S::AbstractMatrix,tmp::AbstractMatrix)
See StoT
for description.
JosephsonCircuits.StoY
— FunctionStoY(S;portimpedances=50.0)
Convert the scattering parameter matrix S
to an admittance parameter matrix Y
and return the result. Assumes a port impedance of 50 Ohms unless specified with the portimpedances
keyword argument.
Examples
julia> S = Complex{Float64}[0.0 0.999;0.999 0.0];JosephsonCircuits.StoY(S)
2×2 Matrix{ComplexF64}:
19.99+0.0im -19.99+0.0im
-19.99+0.0im 19.99+0.0im
References
Russer, Peter. Electromagnetics, Microwave Circuit, And Antenna Design for Communications Engineering, Second Edition. Artech House, 2006.
JosephsonCircuits.StoY!
— MethodStoY!(Y::AbstractMatrix,S::AbstractMatrix,tmp::AbstractMatrix,sqrtportadmittances)
See StoY
for description.
JosephsonCircuits.StoZ
— FunctionStoZ(S;portimpedances=50.0)
Convert the scattering parameter matrix S
to an impedance parameter matrix Z
and return the result. Assumes a port impedance of 50 Ohms unless specified with the portimpedances
keyword argument.
Examples
julia> S = Complex{Float64}[0.0 0.0;0.0 0.0];JosephsonCircuits.StoZ(S)
2×2 Matrix{ComplexF64}:
50.0+0.0im 0.0+0.0im
0.0+0.0im 50.0+0.0im
julia> S = Complex{Float64}[0.0 0.999;0.999 0.0];JosephsonCircuits.StoZ(S)
2×2 Matrix{ComplexF64}:
49975.0+0.0im 49975.0+0.0im
49975.0+0.0im 49975.0+0.0im
References
Russer, Peter. Electromagnetics, Microwave Circuit, And Antenna Design for Communications Engineering, Second Edition. Artech House, 2006.
JosephsonCircuits.StoZ!
— MethodStoZ!(Z::AbstractMatrix,S::AbstractMatrix,tmp::AbstractMatrix,sqrtportimpedances)
See StoZ
for description.
JosephsonCircuits.Stokeyed
— MethodStokeyed(S, outputmodes, outputportnumbers, inputmodes, inputportnumbers)
Convert a scattering parameter array S
to a keyed array. Returned the keyed array.
Examples
julia> JosephsonCircuits.Stokeyed([11 12;21 22],[(0,)],[1,2],[(0,)],[1,2])
4-dimensional KeyedArray(NamedDimsArray(...)) with keys:
↓ outputmode ∈ 1-element Vector{Tuple{Int64}}
→ outputport ∈ 2-element Vector{Int64}
◪ inputmode ∈ 1-element Vector{Tuple{Int64}}
▨ inputport ∈ 2-element Vector{Int64}
And data, 1×2×1×2 Array{Int64, 4}:
[:, :, 1, 1] ~ (:, :, (0,), 1):
(1) (2)
(0,) 11 21
[:, :, 1, 2] ~ (:, :, (0,), 2):
(1) (2)
(0,) 12 22
JosephsonCircuits.Stokeyed
— MethodStokeyed(S, outputmodes, outputportnumbers, inputmodes,
inputportnumbers, w)
Convert a scattering parameter array S
vs frequency w
to a keyed array. Returned the keyed array.
Examples
julia> JosephsonCircuits.Stokeyed([11 12;21 22;;;],[(0,)],[1,2],[(0,)],[1,2],[1.0])
5-dimensional KeyedArray(NamedDimsArray(...)) with keys:
↓ outputmode ∈ 1-element Vector{Tuple{Int64}}
→ outputport ∈ 2-element Vector{Int64}
◪ inputmode ∈ 1-element Vector{Tuple{Int64}}
▨ inputport ∈ 2-element Vector{Int64}
▨ freqindex ∈ 1-element UnitRange{Int64}
And data, 1×2×1×2×1 Array{Int64, 5}:
[:, :, 1, 1, 1] ~ (:, :, (0,), 1, 1):
(1) (2)
(0,) 11 21
[:, :, 1, 2, 1] ~ (:, :, (0,), 2, 1):
(1) (2)
(0,) 12 22
JosephsonCircuits.TtoS
— FunctionTtoS(T)
Convert the transmission matrix T
to a scattering parameter matrix S
and return the result.
Examples
julia> T = Complex{Float64}[1.0 0.0;0.0 1.0];JosephsonCircuits.TtoS(T)
2×2 Matrix{ComplexF64}:
-0.0-0.0im 1.0+0.0im
1.0-0.0im -0.0-0.0im
References
Russer, Peter. Electromagnetics, Microwave Circuit, And Antenna Design for Communications Engineering, Second Edition. Artech House, 2006 with change of sign on T11 and T21 terms (suspected typo).
JosephsonCircuits.TtoS!
— MethodTtoS!(S::AbstractMatrix,T::AbstractMatrix,tmp::AbstractMatrix)
See TtoS
for description.
JosephsonCircuits.Y_PiY!
— MethodY_PiY!(Y,Y1,Y2,Y3)
In-place version of Y_PiY
.
Examples
julia> JosephsonCircuits.Y_PiY!(zeros(Complex{Float64},2,2),1.0,2.0,4.0)
2×2 Matrix{ComplexF64}:
5.0+0.0im -4.0+0.0im
-4.0+0.0im 6.0+0.0im
JosephsonCircuits.Y_PiY
— MethodY_PiY(Y1,Y2,Y3)
Return the admittance matrix for a Pi network of admittances Y1
, Y2
, and Y3
.
o----Y3-----o
| |
Y1 Y2
| |
o-----------o
Examples
julia> JosephsonCircuits.Y_PiY(1.0+0.0im,2.0+0.0im,4.0+0.0im)
2×2 Matrix{ComplexF64}:
5.0+0.0im -4.0-0.0im
-4.0-0.0im 6.0+0.0im
JosephsonCircuits.Y_seriesY!
— MethodY_seriesY!(Y,Y1)
In-place version of Y_seriesY
.
Examples
julia> JosephsonCircuits.Y_seriesY!(zeros(Complex{Float64},2,2),1/50)
2×2 Matrix{ComplexF64}:
0.02+0.0im -0.02+0.0im
-0.02+0.0im 0.02+0.0im
JosephsonCircuits.Y_seriesY
— MethodY_seriesY(Y1)
Return the Y matrix for a series admittance Y1
.
o---Y1---o
o--------o
Examples
julia> JosephsonCircuits.Y_seriesY(1/(50.0+0.0im))
2×2 Matrix{ComplexF64}:
0.02-0.0im -0.02+0.0im
-0.02+0.0im 0.02-0.0im
JosephsonCircuits.YtoA
— FunctionYtoA(Y)
Convert the admittance matrix Y
to the chain (ABCD) matrix A
and return the result.
Examples
julia> Y = Complex{Float64}[1/50 1/50;1/50 1/50];JosephsonCircuits.YtoA(Y)
2×2 Matrix{ComplexF64}:
-1.0+0.0im -50.0+0.0im
0.0+0.0im -1.0+0.0im
References
Russer, Peter. Electromagnetics, Microwave Circuit, And Antenna Design for Communications Engineering, Second Edition. Artech House, 2006 with change of overall sign on (suspected typo).
JosephsonCircuits.YtoA!
— MethodYtoA!(A::AbstractMatrix,Y::AbstractMatrix,tmp::AbstractMatrix)
See YtoA
for description.
JosephsonCircuits.YtoB
— FunctionYtoB(Y)
Convert the admittance matrix Y
to the inverse chain matrix B
and return the result.
Examples
julia> Y = Complex{Float64}[1/50 1/50;1/50 1/50];JosephsonCircuits.YtoB(Y)
2×2 Matrix{ComplexF64}:
-1.0+0.0im -50.0+0.0im
0.0+0.0im -1.0+0.0im
References
Russer, Peter. Electromagnetics, Microwave Circuit, And Antenna Design for Communications Engineering, Second Edition. Artech House, 2006.
JosephsonCircuits.YtoB!
— MethodYtoB!(B::AbstractMatrix,Y::AbstractMatrix,tmp::AbstractMatrix)
See YtoB
for description.
JosephsonCircuits.YtoS
— FunctionYtoS(Y;portimpedances=50.0)
Convert the admittance parameter matrix Y
to a scattering parameter matrix S
and return the result. portimpedances
is a scalar, vector, or matrix of port impedances.
Examples
julia> Y = Complex{Float64}[1/50.0 0.0;0.0 1/50.0];JosephsonCircuits.YtoS(Y)
2×2 Matrix{ComplexF64}:
0.0-0.0im -0.0-0.0im
-0.0-0.0im 0.0-0.0im
References
Russer, Peter. Electromagnetics, Microwave Circuit, And Antenna Design for Communications Engineering, Second Edition. Artech House, 2006.
JosephsonCircuits.YtoS!
— MethodYtoS!(S::AbstractMatrix,Y::AbstractMatrix,tmp::AbstractMatrix,sqrtportimpedances)
See YtoS
for description.
JosephsonCircuits.ZC_basis_coupled_tlines
— MethodZC_basis_coupled_tlines(L, Cmaxwell)
Returns the characteristic impedance matrix `ZC` and eigenbasis for
current `TI` and voltage `TV` from the inductance per unit length matrix
`L` and Maxwell capacitance per unit length matrix `Cmaxwell`.
Arguments
L
: inductance per unit length matrix.C
: Maxwell capacitance per unit length matrix.
Returns
ZC
: characteristic impedance matrix.TI
: matrix which transforms mode currents to currents, I = TIIm. Computed from TI = Utheta*S.TV
: matrix which transforms mode voltages to voltages, V = TVVm. Computed from TV = Uinv(theta)*S.theta
: Diagonal matrix with the square of the eigenvalues of Cmaxwell along the diagonals.U
: eigenvectors of Cmaxwell.lambda
: Diagonal matrix with the square of the eigenvalues of thetaUtLUtheta along the diagonals.lambda
is related to the propagation constant, gamma, as gamma^2 = -omega^2*lambda^2.S
: eigenvectors of thetaUtLUtheta.
Examples
Zeven = 51.0
Zodd = 49.0
neven = 1.1
nodd = 1.08
c = JosephsonCircuits.speed_of_light
L, C = JosephsonCircuits.even_odd_to_maxwell(Zeven, Zodd, neven, nodd)
b = JosephsonCircuits.ZC_basis_coupled_tlines(L,C)
@show b.ZC
@show b.TI
@show b.TV
@show Matrix(b.theta)
@show b.U
@show Matrix(b.lambda)
@show b.S
println(isapprox(Zeven,b.ZC[1,1]+b.ZC[1,2]))
println(isapprox(Zodd,b.ZC[1,1]-b.ZC[1,2]))
println(isapprox(neven,b.lambda[2,2]*c))
println(isapprox(nodd,b.lambda[1,1]*c))
# output
b.ZC = [49.999999999999986 0.9999999999999929; 0.9999999999999929 49.999999999999986]
b.TI = [-6.063012846509498e-6 -5.997716107132906e-6; 6.063012846509498e-6 -5.997716107132906e-6]
b.TV = [-82467.25063230767 -83365.06614665617; 82467.25063230767 -83365.06614665617]
Matrix(b.theta) = [8.48205146197092e-6 0.0; 0.0 8.574394996376037e-6]
b.U = [-0.7071067811865475 -0.7071067811865475; -0.7071067811865475 0.7071067811865475]
Matrix(b.lambda) = [3.6024922281400425e-9 0.0; 0.0 3.669205047179673e-9]
b.S = [0.0 1.0; 1.0 0.0]
true
true
true
true
References
Paul, Clayton R. Analysis of Multiconductor Transmission Lines, Second Edition. Wiley, 2008.
JosephsonCircuits.Z_TZ!
— MethodZ_TZ!(Z,Z1,Z2,Z3)
In-place version of Z_TZ
.
Examples
julia> JosephsonCircuits.Z_TZ!(ones(Complex{Float64},2,2),1,2,4)
2×2 Matrix{ComplexF64}:
5.0+0.0im 4.0+0.0im
4.0+0.0im 6.0+0.0im
JosephsonCircuits.Z_TZ
— MethodZ_TZ(Z1,Z2,Z3)
Return the ABCD matrix for a T network of impedances Z1
, Z2
, and Z3
.
o--Z1-----Z2--o
|
Z3
|
o-------------o
Examples
julia> JosephsonCircuits.Z_TZ(1.0+0.0im,2.0+0.0im,4.0+0.0im)
2×2 Matrix{ComplexF64}:
5.0+0.0im 4.0+0.0im
4.0+0.0im 6.0+0.0im
JosephsonCircuits.Z_canonical_coupled_line_circuits
— MethodZ_canonical_coupled_line_circuit(i::Int, Z0e, Z0o, thetae, thetao)
Return the impedance matrix for the i
'th canonical coupled line circuit, as a function of the even mode phase delay thetae
in radians, the odd mode phase delay thetao
in radians, the even mode characteristic impedance Z0e
in Ohms, and the odd mode characteristic impedance Z0o
in Ohms.
- low pass
gnd--==========
1--> o--==========--o <--2
- band pass
gnd--==========--o <--2
1--> o--==========--gnd
- band pass
==========--o <--2
1--> o--==========
- band pass
1--> o--==========--gnd
2--> o--==========
- all pass
==========
1--> o--==========--o <--2
- all pass
gnd--==========--gnd
1--> o--==========--o <--2
- all pass
1--> o--==========--|
2--> o--==========--|
- all stop
gnd--==========--o <--2
1--> o--==========
- all stop
1--> o--==========--gnd
2--> o--==========--gnd
- all stop
1--> o--==========
2--> o--==========
Examples
julia> @variables θe, θo, Ze, Zo;JosephsonCircuits.Z_canonical_coupled_line_circuits(3,Ze,Zo,θe,θo)
2×2 Matrix{Complex{Num}}:
-0.5(Ze*cot(θe) + Zo*cot(θo))*im -0.5(Ze*csc(θe) - Zo*csc(θo))*im
-0.5(Ze*csc(θe) - Zo*csc(θo))*im -0.5(Ze*cot(θe) + Zo*cot(θo))*im
References
E. M. T. Jones, "Coupled-Strip-Transmission-Line Filters and Directional Couplers," in IRE Transactions on Microwave Theory and Techniques, vol. 4, no. 2, pp. 75-81, April 1956, doi: 10.1109/TMTT.1956.1125022.
Pozar, D. M. Microwave Engineering (4 ed.). John Wiley & Sons (2011) ISBN 9780470631553.
JosephsonCircuits.Z_coupled_tline!
— MethodZ_coupled_tline!(Z, Z0e, Z0o, thetae, thetao)
In-place version of Z_coupled_tline
.
Examples
julia> JosephsonCircuits.Z_coupled_tline!(zeros(Complex{Float64},4,4),50,50,pi/4,pi/4)
4×4 Matrix{ComplexF64}:
0.0-50.0im 0.0-0.0im 0.0-70.7107im 0.0-0.0im
0.0-0.0im 0.0-50.0im 0.0-0.0im 0.0-70.7107im
0.0-70.7107im 0.0-0.0im 0.0-50.0im 0.0-0.0im
0.0-0.0im 0.0-70.7107im 0.0-0.0im 0.0-50.0im
JosephsonCircuits.Z_coupled_tline
— MethodZ_coupled_tline(Z0e, Z0o, thetae, thetao)
Return the impedance matrix for two coupled transmission lines described even and odd mode impedances Z0e
and Z0o
and by even and odd mode phase delays thetae
and thetao
.
thetae, Z0e
thetao, Z0o
V1, I1 --> ======== <-- I3, V3
V2, I2 --> ======== <-- I4, V4
[(V1+V2)/2, (I1+I2)/2] = ABCDe * [(V3+V4)/2, -(I3+I4)/2]
[(V1-V2)/2, (I1-I2)/2] = ABCDo * [(V3-V4)/2, -(I3-I4)/2]
[V1, V2, V3, V4] = Z_coupled_tline * [I1, I2, I3, I4]
Examples
julia> JosephsonCircuits.Z_coupled_tline(50,50,pi/4,pi/4)
4×4 Matrix{ComplexF64}:
0.0-50.0im 0.0-0.0im 0.0-70.7107im 0.0-0.0im
0.0-0.0im 0.0-50.0im 0.0-0.0im 0.0-70.7107im
0.0-70.7107im 0.0-0.0im 0.0-50.0im 0.0-0.0im
0.0-0.0im 0.0-70.7107im 0.0-0.0im 0.0-50.0im
JosephsonCircuits.Z_shuntZ!
— MethodZ_shuntZ!(Z,Z1)
In-place version of Z_shuntZ
.
Examples
julia> JosephsonCircuits.Z_shuntZ!(zeros(Complex{Float64},2,2),50)
2×2 Matrix{ComplexF64}:
50.0+0.0im 50.0+0.0im
50.0+0.0im 50.0+0.0im
JosephsonCircuits.Z_shuntZ
— MethodZ_shuntZ(Z1)
Return the Z matrix for a shunt impedance Z1
.
o---------o
|
Z1
|
o---------o
Examples
julia> JosephsonCircuits.Z_shuntZ(50.0+0.0im)
2×2 Matrix{ComplexF64}:
50.0+0.0im 50.0+0.0im
50.0+0.0im 50.0+0.0im
JosephsonCircuits.Z_tline!
— MethodZ_tline!(Z, Z0, theta)
In-place version of Z_tline
.
Examples
julia> JosephsonCircuits.Z_tline!(ones(Complex{Float64},2,2),50, pi/4)
2×2 Matrix{ComplexF64}:
0.0-50.0im 0.0-70.7107im
0.0-70.7107im 0.0-50.0im
JosephsonCircuits.Z_tline
— MethodZ_tline(Z0, theta)
Return the impedance matrix for a transmission line described by a characteristic impedance Z0
in Ohms and phase delay theta
in radians
theta, Z0
o--========--o
o------------o
Examples
julia> JosephsonCircuits.Z_tline(50, pi/4)
2×2 Matrix{ComplexF64}:
0.0-50.0im 0.0-70.7107im
0.0-70.7107im 0.0-50.0im
JosephsonCircuits.ZtoA
— FunctionZtoA(Z)
Convert the impedance matrix Z
to the ABCD matrix A
and return the result.
Examples
julia> Z = Complex{Float64}[50.0 50.0;50.0 50.0];JosephsonCircuits.ZtoA(Z)
2×2 Matrix{ComplexF64}:
1.0+0.0im 0.0-0.0im
0.02+0.0im 1.0+0.0im
References
Russer, Peter. Electromagnetics, Microwave Circuit, And Antenna Design for Communications Engineering, Second Edition. Artech House, 2006.
JosephsonCircuits.ZtoA!
— MethodZtoA!(A::AbstractMatrix,Z::AbstractMatrix,tmp::AbstractMatrix)
See ZtoA
for description.
JosephsonCircuits.ZtoB
— FunctionZtoB(Z)
Convert the impedance matrix Z
to the inverse chain matrix B
and return the result.
Examples
julia> Z = Complex{Float64}[50.0 50;50 50];JosephsonCircuits.ZtoB(Z)
2×2 Matrix{ComplexF64}:
1.0+0.0im 0.0-0.0im
0.02+0.0im 1.0+0.0im
References
Russer, Peter. Electromagnetics, Microwave Circuit, And Antenna Design for Communications Engineering, Second Edition. Artech House, 2006.
JosephsonCircuits.ZtoB!
— MethodZtoB!(B::AbstractMatrix,Z::AbstractMatrix,tmp::AbstractMatrix)
See ZtoB
for description.
JosephsonCircuits.ZtoS
— FunctionZtoS(Z;portimpedances=50.0)
Convert the impedance parameter matrix Z
to a scattering parameter matrix S
and return the result. portimpedances
is a scalar, vector, or matrix of port impedances. Assumes a port impedance of 50 Ohms unless specified with the portimpedances
keyword argument.
Examples
julia> Z = Complex{Float64}[0.0 0.0;0.0 0.0];JosephsonCircuits.ZtoS(Z)
2×2 Matrix{ComplexF64}:
-1.0+0.0im 0.0-0.0im
0.0-0.0im -1.0+0.0im
References
Russer, Peter. Electromagnetics, Microwave Circuit, And Antenna Design for Communications Engineering, Second Edition. Artech House, 2006.
JosephsonCircuits.ZtoS!
— MethodZtoS!(S::AbstractMatrix,Z::AbstractMatrix,tmp::AbstractMatrix,sqrtportimpedances)
See ZtoS
for description.
JosephsonCircuits.add_ports
— Methodadd_ports(networks)
Return the vector of networks networks
with ports added.
Examples
julia> networks = [(:S1,[0.0 1.0;1.0 0.0]),(:S2,[0.5 0.5;0.5 0.5])];JosephsonCircuits.add_ports(networks)
2-element Vector{Tuple{Symbol, Matrix{Float64}, Vector{Tuple{Symbol, Int64}}}}:
(:S1, [0.0 1.0; 1.0 0.0], [(:S1, 1), (:S1, 2)])
(:S2, [0.5 0.5; 0.5 0.5], [(:S2, 1), (:S2, 2)])
julia> networks = [(:S1,[0.0 1.0;1.0 0.0],[(:S1,1),(:S1,2)]),(:S2,[0.5 0.5;0.5 0.5],[(:S3,1),(:S3,2)])];JosephsonCircuits.add_ports(networks)
2-element Vector{Tuple{Symbol, Matrix{Float64}, Vector{Tuple{Symbol, Int64}}}}:
(:S1, [0.0 1.0; 1.0 0.0], [(:S1, 1), (:S1, 2)])
(:S2, [0.5 0.5; 0.5 0.5], [(:S3, 1), (:S3, 2)])
JosephsonCircuits.add_splitters
— Methodadd_splitters(networks::AbstractVector{Tuple{T,N}},
connections::AbstractVector{<:AbstractVector{Tuple{T,Int}}};
splitter_name_length = 20) where {T,N}
Return the networks
and connections
with splitters (ideal lossless symmetrical reciprocal networks) and connections to the splitters added when more than two ports intersect. connections
is also converted from a vector of vectors of tuples where the tuple contains the network and the port such as [[(:S1,1),(:S2,1)]] to a vector of tuples where the tuple contains the two networks and ports being connected [(S1,:S2,1,1)].
References
S. F. Cao, Y. C. Jiao, and Z. Zhang. "Applications of Generalized Cascade Scattering Matrix on the Microwave Circuits and Antenna Arrays". International Journal of Antennas and Propagation Vol. 2015, 759439, doi:10.1155/2015/759439.
JosephsonCircuits.add_splitters
— Methodadd_splitters(networks, connections::AbstractVector{Tuple{T,T,Int,Int}};
kwargs...)) where T
If the connections are already in the correct format, just return them. This function assumes ports have already been added to networks
.
JosephsonCircuits.addsources!
— Methodaddsources!(bbm, modes, sources, portindices, portnumbers,
nodeindices, edge2indexdict, Lmean, Nnodes, Nbranches, Nmodes)
Calculate the source terms in the branch basis. Overwrite bbm with the output. See also calcsources
.
JosephsonCircuits.applynl!
— Methodapplynl!(fd::Array{Complex{T}}, td::Array{T}, f::Function, irfftplan,
rfftplan)
Apply the nonlinear function f to the frequency domain data by transforming to the time domain, applying the function, then transforming back to the frequency domain, overwriting the contents of fd and td in the process. We use plans for the forward and reverse RFFT prepared by plan_applynl
.
Examples
fd=ones(Complex{Float64},3,2)
td, irfftplan, rfftplan = JosephsonCircuits.plan_applynl(fd)
JosephsonCircuits.applynl!(fd, td, cos, irfftplan, rfftplan)
fd
# output
3×2 Matrix{ComplexF64}:
0.586589+0.0im 0.586589+0.0im
-0.413411+0.0im -0.413411+0.0im
-0.413411+0.0im -0.413411+0.0im
JosephsonCircuits.applynl
— Methodapplynl(am::Array{Complex{Float64}}, f::Function)
Perform the inverse discrete Fourier transform on an array am
of complex frequency domain data, apply the function f
in the time domain, then perform the discrete Fourier transform to return to the frequency domain. Apply the Fourier transform on all but the last dimensions. See also applynl!
and plan_applynl
.
Examples
julia> JosephsonCircuits.applynl([[0, 0.2+0.0im, 0, 0];;],cos)
4×1 Matrix{ComplexF64}:
0.9603980498951228 + 0.0im
0.0 + 0.0im
-0.01966852794611884 + 0.0im
0.0 + 0.0im
julia> JosephsonCircuits.applynl([[0, 0.2+0.0im];;],cos)
2×1 Matrix{ComplexF64}:
0.9603980498951228 + 0.0im
-0.01966852794611884 + 0.0im
julia> JosephsonCircuits.applynl([0.0 + 0.0im 0.45 + 0.0im 0.45 + 0.0im; 0.55 + 0.0im 0.0 + 0.0im 0.0 + 0.0im; 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im;;;],sin)
3×3×1 Array{ComplexF64, 3}:
[:, :, 1] =
-0.0209812+0.0im 0.295151+0.0im 0.295151+0.0im
0.359826+0.0im -0.041417+0.0im -0.041417+0.0im
0.00788681+0.0im -0.110947+0.0im -0.110947+0.0im
JosephsonCircuits.arraytonetworkdata
— Methodarraytonetworkdata(frequencies,N, numberofports, numberoffrequencies,
matrixformat, twoportdataorder, parameter, frequencyunit, format, R,
version)
Return a vector with a frequency followed by the network data parameters for that frequency.
Examples
frequencies = 4.0e9:5.0e8:6.0e9
N = [0.9546262517670427 - 0.296397700700921im;;; 0.8915960960938982 - 0.44358732281729774im;;; 0.9857309246425359 + 0.046691189499470154im;;; 0.9759591344506418 - 0.21128542054786678im;;; 0.9604441706426364 - 0.2762239892126382im]
numberofports = 1
numberoffrequencies = 5
matrixformat = "Full"
twoportdataorder = "12_21"
parameter = "S"
frequencyunit = "GHz"
format = "MA"
R = 50.0
version = 2.0
JosephsonCircuits.arraytonetworkdata(frequencies,N, numberofports, numberoffrequencies,
matrixformat, twoportdataorder, parameter, frequencyunit, format, R, version)
# output
15-element Vector{Float64}:
4.0
0.9995813511383583
-17.248815971093425
4.5
0.9958480363660398
-26.451285931791276
5.0
0.9868361175866559
2.711906450972103
5.5
0.9985678550072272
-12.21545548845392
6.0
0.9993761539770525
-16.045248853866596
frequencies = 4.0e9:5.0e8:6.0e9
N = [0.9546262517670427 - 0.296397700700921im;;; 0.8915960960938982 - 0.44358732281729774im;;; 0.9857309246425359 + 0.046691189499470154im;;; 0.9759591344506418 - 0.21128542054786678im;;; 0.9604441706426364 - 0.2762239892126382im]
numberofports = 1
numberoffrequencies = 5
matrixformat = "Lower"
twoportdataorder = "12_21"
parameter = "Z"
frequencyunit = "GHz"
format = "MA"
R = 50.0
version = 2.0
JosephsonCircuits.arraytonetworkdata(frequencies,N, numberofports,
numberoffrequencies, matrixformat, twoportdataorder, parameter,
frequencyunit, format, R, version)
# output
15-element Vector{Float64}:
4.0
0.9995813511383583
-17.248815971093425
4.5
0.9958480363660398
-26.451285931791276
5.0
0.9868361175866559
2.711906450972103
5.5
0.9985678550072272
-12.21545548845392
6.0
0.9993761539770525
-16.045248853866596
frequencies = 4.0e9:5.0e8:6.0e9
N = [0.9546262517670427 - 0.296397700700921im;;; 0.8915960960938982 - 0.44358732281729774im;;; 0.9857309246425359 + 0.046691189499470154im;;; 0.9759591344506418 - 0.21128542054786678im;;; 0.9604441706426364 - 0.2762239892126382im]
numberofports = 1
numberoffrequencies = 5
matrixformat = "Lower"
twoportdataorder = "12_21"
parameter = "Z"
frequencyunit = "GHz"
format = "MA"
R = 50.0
version = 1.0
JosephsonCircuits.arraytonetworkdata(frequencies,N, numberofports,
numberoffrequencies, matrixformat, twoportdataorder, parameter,
frequencyunit, format, R, version)
# output
15-element Vector{Float64}:
4.0
0.019991627022767165
-17.248815971093425
4.5
0.019916960727320795
-26.451285931791276
5.0
0.01973672235173312
2.7119064509721027
5.5
0.019971357100144544
-12.215455488453918
6.0
0.019987523079541047
-16.0452488538666
JosephsonCircuits.calcAoLjbm
— MethodcalcAoLjbm(Am, Ljb::SparseVector, Lmean, Nmodes, Nbranches)
Examples
julia> @variables Lj1 Lj2 A11 A12 A21 A22 A31 A32;JosephsonCircuits.calcAoLjbm([A11;A21;A31],JosephsonCircuits.SparseArrays.sparsevec([1],[Lj1]),1,2,1)
2×2 SparseArrays.SparseMatrixCSC{Num, Int64} with 4 stored entries:
A11 / Lj1 A31 / Lj1
A31 / Lj1 A11 / Lj1
julia> @variables Lj1 Lj2 A11 A12 A21 A22 A31 A32;JosephsonCircuits.calcAoLjbm([A11 A12;A21 A22;A31 A32],JosephsonCircuits.SparseArrays.sparsevec([1,2],[Lj1,Lj2]),1,2,2)
4×4 SparseArrays.SparseMatrixCSC{Num, Int64} with 8 stored entries:
A11 / Lj1 A31 / Lj1 ⋅ ⋅
A31 / Lj1 A11 / Lj1 ⋅ ⋅
⋅ ⋅ A12 / Lj2 A32 / Lj2
⋅ ⋅ A32 / Lj2 A12 / Lj2
julia> @variables Lj1 Lj2 A11 A12 A21 A22 A31 A32;JosephsonCircuits.calcAoLjbm([A11;A21;A31],JosephsonCircuits.SparseArrays.sparsevec([1],[Lj1]),1,3,1)
3×3 SparseArrays.SparseMatrixCSC{Num, Int64} with 9 stored entries:
A11 / Lj1 A31 / Lj1 0
A31 / Lj1 A11 / Lj1 A31 / Lj1
0 A31 / Lj1 A11 / Lj1
JosephsonCircuits.calcAoLjbm2
— MethodcalcAoLjbm2(Am::Array, Amatrixindices::Matrix, Ljb::SparseVector, Lmean,
Nmodes, Nbranches, Nfreq)
Return the harmonic balance matrix divided by the Josephson inductance.
Examples
Amatrix = ComplexF64[1.0 + 1.0im 1.0 + 1.0im; 1.0 + 1.0im 1.0 + 1.0im; 1.0 + 1.0im 1.0 + 1.0im]
Amatrixindices = [1 -2 -3; 2 1 -2; 3 2 1]
Ljb = JosephsonCircuits.SparseArrays.sparsevec([1,2],[1.0,2.0])
Lmean = 1
Nmodes = 3
Nbranches = 2
JosephsonCircuits.calcAoLjbm2(Amatrix, Amatrixindices, Ljb, Lmean, Nmodes, Nbranches)
# output
6×6 SparseArrays.SparseMatrixCSC{ComplexF64, Int64} with 18 stored entries:
1.0+1.0im 1.0-1.0im 1.0-1.0im ⋅ ⋅ ⋅
1.0+1.0im 1.0+1.0im 1.0-1.0im ⋅ ⋅ ⋅
1.0+1.0im 1.0+1.0im 1.0+1.0im ⋅ ⋅ ⋅
⋅ ⋅ ⋅ 0.5+0.5im 0.5-0.5im 0.5-0.5im
⋅ ⋅ ⋅ 0.5+0.5im 0.5+0.5im 0.5-0.5im
⋅ ⋅ ⋅ 0.5+0.5im 0.5+0.5im 0.5+0.5im
Amatrix = ComplexF64[1.0 + 1.0im 1.0 + 1.0im; 1.0 + 1.0im 1.0 + 1.0im; 1.0 + 1.0im 1.0 + 1.0im]
Amatrixindices = [1 -2 0; 2 1 -2; 0 2 1]
Ljb = JosephsonCircuits.SparseArrays.sparsevec([1,2],[1.0,2.0])
Lmean = 1
Nmodes = 3
Nbranches = 2
JosephsonCircuits.calcAoLjbm2(Amatrix, Amatrixindices, Ljb, Lmean, Nmodes, Nbranches)
# output
6×6 SparseArrays.SparseMatrixCSC{ComplexF64, Int64} with 14 stored entries:
1.0+1.0im 1.0-1.0im ⋅ ⋅ ⋅ ⋅
1.0+1.0im 1.0+1.0im 1.0-1.0im ⋅ ⋅ ⋅
⋅ 1.0+1.0im 1.0+1.0im ⋅ ⋅ ⋅
⋅ ⋅ ⋅ 0.5+0.5im 0.5-0.5im ⋅
⋅ ⋅ ⋅ 0.5+0.5im 0.5+0.5im 0.5-0.5im
⋅ ⋅ ⋅ ⋅ 0.5+0.5im 0.5+0.5im
@variables A11 A12 A21 A22 A31 A32 Lj1 Lj2
Amatrix = [A11 A12;A21 A22;A31 A32]
Amatrixindices = [1 -2 -3; 2 1 -2; 3 2 1]
Ljb = JosephsonCircuits.SparseArrays.sparsevec([1,2],[Lj1,Lj2])
Lmean = 1
Nmodes = 3
Nbranches = 2
JosephsonCircuits.calcAoLjbm2(Amatrix, Amatrixindices, Ljb, Lmean, Nmodes, Nbranches)
# output
6×6 SparseArrays.SparseMatrixCSC{Num, Int64} with 18 stored entries:
A11 / Lj1 A21 / Lj1 A31 / Lj1 ⋅ ⋅ ⋅
A21 / Lj1 A11 / Lj1 A21 / Lj1 ⋅ ⋅ ⋅
A31 / Lj1 A21 / Lj1 A11 / Lj1 ⋅ ⋅ ⋅
⋅ ⋅ ⋅ A12 / Lj2 A22 / Lj2 A32 / Lj2
⋅ ⋅ ⋅ A22 / Lj2 A12 / Lj2 A22 / Lj2
⋅ ⋅ ⋅ A32 / Lj2 A22 / Lj2 A12 / Lj2
JosephsonCircuits.calcAoLjbmindices
— MethodcalcAoLjbmindices(Amatrixindices, Ljb::SparseVector, Nmodes, Nbranches,
Nfreq)
Return the sparse matrix containing the indices from the frequency domain RFFT data as well as the indices of the sparse matrix to conjugate.
Examples
Amatrixindices = [1 -2 -3 -4; 2 1 -2 -3; 3 2 1 -2; 4 3 2 1]
Ljb = JosephsonCircuits.SparseArrays.sparsevec([1,2],[1.0,1.0])
Nmodes = 4
Nbranches = length(Ljb)
Nfreq = 4
AoLjbmindices, conjindicessorted, nentries = JosephsonCircuits.calcAoLjbmindices(
Amatrixindices,
Ljb,
Nmodes,
Nbranches,
Nfreq);
AoLjbmindices
# output
8×8 SparseArrays.SparseMatrixCSC{Int64, Int64} with 32 stored entries:
1 2 3 4 ⋅ ⋅ ⋅ ⋅
2 1 2 3 ⋅ ⋅ ⋅ ⋅
3 2 1 2 ⋅ ⋅ ⋅ ⋅
4 3 2 1 ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ 5 6 7 8
⋅ ⋅ ⋅ ⋅ 6 5 6 7
⋅ ⋅ ⋅ ⋅ 7 6 5 6
⋅ ⋅ ⋅ ⋅ 8 7 6 5
Amatrixindices = [1 -2 -3 0; 2 1 -2 -3; 3 2 1 -2; 0 3 2 1]
Ljb = JosephsonCircuits.SparseArrays.sparsevec([1,2],[1.0,1.0])
Nmodes = 4
Nbranches = length(Ljb)
Nfreq = 4
AoLjbmindices, conjindicessorted, nentries = JosephsonCircuits.calcAoLjbmindices(
Amatrixindices,
Ljb,
Nmodes,
Nbranches,
Nfreq);
AoLjbmindices
# output
8×8 SparseArrays.SparseMatrixCSC{Int64, Int64} with 28 stored entries:
1 2 3 ⋅ ⋅ ⋅ ⋅ ⋅
2 1 2 3 ⋅ ⋅ ⋅ ⋅
3 2 1 2 ⋅ ⋅ ⋅ ⋅
⋅ 3 2 1 ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ 5 6 7 ⋅
⋅ ⋅ ⋅ ⋅ 6 5 6 7
⋅ ⋅ ⋅ ⋅ 7 6 5 6
⋅ ⋅ ⋅ ⋅ ⋅ 7 6 5
Amatrixindices = [1 -2 -3 -4; 2 1 -2 -3; 3 2 1 -2; 4 3 2 1]
Ljb = JosephsonCircuits.SparseArrays.sparsevec([1,3],[1.0,1.0])
Nmodes = 4
Nbranches = length(Ljb)
Nfreq = 4
AoLjbmindices, conjindicessorted, nentries = JosephsonCircuits.calcAoLjbmindices(
Amatrixindices,
Ljb,
Nmodes,
Nbranches,
Nfreq);
for c in conjindicessorted;AoLjbmindices.nzval[c] = -AoLjbmindices.nzval[c];end;AoLjbmindices
# output
12×12 SparseArrays.SparseMatrixCSC{Int64, Int64} with 32 stored entries:
1 -2 -3 -4 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
2 1 -2 -3 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
3 2 1 -2 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
4 3 2 1 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 5 -6 -7 -8
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 6 5 -6 -7
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 7 6 5 -6
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 8 7 6 5
JosephsonCircuits.calcCjIcmean
— MethodcalcCjIcmean(componenttypes::Vector{Symbol}, nodeindexarray::Matrix{Int},
componentvalues::Vector, componentnamedict::Dict,
mutualinductorbranchnames::Vector{String}, countdict::Dict,
indexdict::Dict)
Calculate the junction properties including the max and min critical currents and ratios of critical current to junction capacitance. This is necessary in order to set the junction properties of the JJ model in WRSPICE.
Examples
componenttypes = [:P, :R, :C, :Lj, :C, :C, :Lj, :C]
nodeindexarray = [2 2 2 3 3 3 4 4; 1 1 3 1 1 4 1 1]
componentvalues = Real[1, 50.0, 1.0e-13, 1.0e-9, 1.0e-12, 1.0e-13, 1.1e-9, 1.2e-12]
componentnamedict = Dict("R1" => 2, "Cc2" => 6, "Cj2" => 8, "Cj1" => 5, "P1" => 1, "Cc1" => 3, "Lj2" => 7, "Lj1" => 4)
mutualinductorbranchnames = String[]
countdict = Dict((:Lj, 1, 4) => 1, (:C, 3, 4) => 1, (:C, 1, 4) => 1, (:Lj, 1, 3) => 1, (:R, 1, 2) => 1, (:P, 1, 2) => 1, (:C, 1, 3) => 1, (:C, 2, 3) => 1)
indexdict = Dict((:C, 2, 3, 1) => 3, (:Lj, 1, 3, 1) => 4, (:C, 1, 3, 1) => 5, (:R, 1, 2, 1) => 2, (:C, 3, 4, 1) => 6, (:P, 1, 2, 1) => 1, (:C, 1, 4, 1) => 8, (:Lj, 1, 4, 1) => 7)
Cj, Icmean = JosephsonCircuits.calcCjIcmean(componenttypes, nodeindexarray,
componentvalues, componentnamedict,mutualinductorbranchnames, countdict, indexdict)
# output
(3.1100514732000003e-13, 3.1414661345454545e-7)
componenttypes = [:P, :R, :C, :Lj, :C, :C, :Lj, :C]
nodeindexarray = [2 2 2 3 3 3 4 4; 1 1 3 1 1 4 1 1]
componentvalues = Real[1, 50.0, 1.0e-13, 2.0e-9, 1.0e-12, 1.0e-13, 1.1e-9, 1.2e-12]
componentnamedict = Dict("R1" => 2, "Cc2" => 6, "Cj2" => 8, "Cj1" => 5, "P1" => 1, "Cc1" => 3, "Lj2" => 7, "Lj1" => 4)
mutualinductorbranchnames = String[]
countdict = Dict((:Lj, 1, 4) => 1, (:C, 3, 4) => 1, (:C, 1, 4) => 1, (:Lj, 1, 3) => 1, (:R, 1, 2) => 1, (:P, 1, 2) => 1, (:C, 1, 3) => 1, (:C, 2, 3) => 1)
indexdict = Dict((:C, 2, 3, 1) => 3, (:Lj, 1, 3, 1) => 4, (:C, 1, 3, 1) => 5, (:R, 1, 2, 1) => 2, (:C, 3, 4, 1) => 6, (:P, 1, 2, 1) => 1, (:C, 1, 4, 1) => 8, (:Lj, 1, 4, 1) => 7)
Cj, Icmean = JosephsonCircuits.calcCjIcmean(componenttypes, nodeindexarray,
componentvalues, componentnamedict,mutualinductorbranchnames, countdict, indexdict)
# output
(2.2955141825999997e-13, 2.3187011945454544e-7)
JosephsonCircuits.calcCn
— MethodcalcCn(componenttypes::Vector{Symbol}, nodeindices::Matrix{Int},
componentvalues::Vector, Nmodes, Nnodes)
Returns the node capacitance matrix from the capacitance values in componentvalues
when componenttypes
has the symbol :C
with node indices from nodeindices
. Other symbols are ignored. Capacitances to ground become diagonal elements. Capacitance between elements is an off-diagonal element with a minus sign and is added to the diagonal with a plus sign. The dimensions of the output are (Nnodes-1)*Nmodes
by (Nnodes-1)
times Nmodes
where Nnodes
is the number of nodes including ground and Nmodes
is the number of different frequencies. Note that nodeindices
is "one indexed" so 1 is the ground node.
Examples
julia> JosephsonCircuits.calcCn([:C,:C],[2 3;1 1],[1.0,2.0],1,3)
2×2 SparseArrays.SparseMatrixCSC{Float64, Int64} with 2 stored entries:
1.0 ⋅
⋅ 2.0
julia> JosephsonCircuits.calcCn([:C,:C,:C],[2 2 3;1 3 1],[1.0,0.1,2.0],1,3)
2×2 SparseArrays.SparseMatrixCSC{Float64, Int64} with 4 stored entries:
1.1 -0.1
-0.1 2.1
julia> JosephsonCircuits.calcCn([:C,:C,:C],[2 2 3;1 3 1],[1.0,0.1,2.0],2,3)
4×4 SparseArrays.SparseMatrixCSC{Float64, Int64} with 8 stored entries:
1.1 ⋅ -0.1 ⋅
⋅ 1.1 ⋅ -0.1
-0.1 ⋅ 2.1 ⋅
⋅ -0.1 ⋅ 2.1
julia> @variables Cg1 Cg2;JosephsonCircuits.calcCn([:C,:C],[2 3;1 1],[Cg1,Cg2],1,3)
2×2 SparseArrays.SparseMatrixCSC{Num, Int64} with 2 stored entries:
Cg1 ⋅
⋅ Cg2
julia> @variables Cg1 Cc Cg2;JosephsonCircuits.calcCn([:C,:C,:C],[2 2 3;1 3 1],[Cg1, Cc, Cg1],1,3)
2×2 SparseArrays.SparseMatrixCSC{Num, Int64} with 4 stored entries:
Cc + Cg1 -Cc
-Cc Cc + Cg1
julia> @variables Cg1 Cc Cg2;JosephsonCircuits.calcCn([:C,:C,:C],[2 2 3;1 3 1],[Cg1, Cc, Cg1],2,3)
4×4 SparseArrays.SparseMatrixCSC{Num, Int64} with 8 stored entries:
Cc + Cg1 ⋅ -Cc ⋅
⋅ Cc + Cg1 ⋅ -Cc
-Cc ⋅ Cc + Cg1 ⋅
⋅ -Cc ⋅ Cc + Cg1
JosephsonCircuits.calcGn
— MethodcalcGn(componenttypes::Vector{Symbol}, nodeindices::Matrix{Int},
componentvalues::Vector, Nmodes, Nnodes)
Returns the node conductance matrix from the resistance values in componentvalues
when componenttypes
has the symbol :R
. The node indices are taken from nodeindices
. Conductances to ground are diagonal elements. Conductance between elements is an off-diagonal element with a minus sign and is added to the diagonal with a plus sign. The dimensions of the output are (Nnodes-1)
times Nmodes
by (Nnodes-1)
times Nmodes
. Note that nodeindices
is "one indexed" so 1 is the ground node.
We have to calculate the inverse of the individual components so select a type that allows that.
Examples
julia> JosephsonCircuits.calcGn([:R,:R],[2 3;1 1],[1.0,2.0],1,3)
2×2 SparseArrays.SparseMatrixCSC{Float64, Int64} with 2 stored entries:
1.0 ⋅
⋅ 0.5
julia> JosephsonCircuits.calcGn([:R,:R,:R],[2 2 3;1 3 1],[1.0,100.0,2.0],1,3)
2×2 SparseArrays.SparseMatrixCSC{Float64, Int64} with 4 stored entries:
1.01 -0.01
-0.01 0.51
julia> JosephsonCircuits.calcGn([:R,:R,:R],[1 3 1;2 2 3],[1.0,100.0,2.0],1,3)
2×2 SparseArrays.SparseMatrixCSC{Float64, Int64} with 4 stored entries:
1.01 -0.01
-0.01 0.51
julia> JosephsonCircuits.calcGn([:R,:R,:R],[2 2 3;1 3 1],[1.0,100.0,2.0],2,3)
4×4 SparseArrays.SparseMatrixCSC{Float64, Int64} with 8 stored entries:
1.01 ⋅ -0.01 ⋅
⋅ 1.01 ⋅ -0.01
-0.01 ⋅ 0.51 ⋅
⋅ -0.01 ⋅ 0.51
julia> @variables Rg1 Rg2;JosephsonCircuits.calcGn([:R,:R],[2 3;1 1],[Rg1,Rg2],1,3)
2×2 SparseArrays.SparseMatrixCSC{Num, Int64} with 2 stored entries:
1 / Rg1 ⋅
⋅ 1 / Rg2
julia> @variables Rg1 Rc Rg2;JosephsonCircuits.calcGn([:R,:R,:R],[2 2 3;1 3 1],[Rg1,Rc,Rg2],1,3)
2×2 SparseArrays.SparseMatrixCSC{Num, Int64} with 4 stored entries:
1 / Rg1 + 1 / Rc -1 / Rc
-1 / Rc 1 / Rg2 + 1 / Rc
julia> @variables Rg1 Rc Rg2;JosephsonCircuits.calcGn([:R,:R,:R],[2 2 3;1 3 1],[Rg1,Rc,Rg2],2,3)
4×4 SparseArrays.SparseMatrixCSC{Num, Int64} with 8 stored entries:
1 / Rg1 + 1 / Rc ⋅ -1 / Rc ⋅
⋅ 1 / Rg1 + 1 / Rc ⋅ -1 / Rc
-1 / Rc ⋅ 1 / Rg2 + 1 / Rc ⋅
⋅ -1 / Rc ⋅ 1 / Rg2 + 1 / Rc
JosephsonCircuits.calcIb
— MethodcalcIb(componenttypes::Vector{Symbol}, nodeindices::Matrix{Int},
componentvalues::Vector, edge2indexdict::Dict, Nmodes, Nbranches)
Calculate the sparse branch current source vector whose length is Nbranches*Nmodes
. Note that nodeindices
is "one indexed" so 1 is the ground node.
Examples
Nmodes = 1
Nbranches = 2
componenttypes = [:I,:C,:L,:C]
nodeindices = [2 0 3 3; 1 0 1 1]
componentvalues = [1e-9, 0.2, 4e-9, 1e-12]
componentnamedict = Dict{Symbol, Int}(:C2 => 4,:L1 => 3,:I1 => 1,:C1 => 2)
edge2indexdict = Dict{Tuple{Int, Int}, Int}((1, 2) => 1,(3, 1) => 2,(1, 3) => 2,(2, 1) => 1)
Ib = JosephsonCircuits.calcIb(componenttypes,nodeindices,componentvalues,edge2indexdict,Nmodes,Nbranches)
JosephsonCircuits.testshow(stdout,Ib)
# output
sparsevec([1], [1.0e-9], 2)
@variables I1 C1 L1 C2
Nmodes = 1
Nbranches = 2
componenttypes = [:I,:C,:L,:C]
nodeindices = [2 0 3 3; 1 0 1 1]
componentvalues = [I1, C1, L1, C2]
componentnamedict = Dict{Symbol, Int}(:C2 => 4,:L1 => 3,:I1 => 1,:C1 => 2)
edge2indexdict = Dict{Tuple{Int, Int}, Int}((1, 2) => 1,(3, 1) => 2,(1, 3) => 2,(2, 1) => 1)
Ib = JosephsonCircuits.calcIb(componenttypes,nodeindices,componentvalues,edge2indexdict,Nmodes,Nbranches)
JosephsonCircuits.testshow(stdout,Ib)
# output
sparsevec([1], Num[I1], 2)
JosephsonCircuits.calcLb
— MethodcalcLb(componenttypes::Vector{Symbol}, nodeindices::Matrix{Int},
componentvalues::Vector, edge2indexdict::Dict, Nmodes, Nbranches)
Calculate the sparse branch inductance vector whose length is Nbranches*Nmodes
. Note that nodeindices
is "one indexed" so 1 is the ground node.
Examples
Nmodes = 1
Nbranches = 2
componenttypes = [:L,:K,:L,:C]
nodeindices = [2 0 3 3; 1 0 1 1]
componentvalues = [1e-9, 0.2, 4e-9, 1e-12]
componentnamedict = Dict{Symbol, Int}(:C2 => 4,:L2 => 3,:L1 => 1,:K1 => 2)
edge2indexdict = Dict{Tuple{Int, Int}, Int}((1, 2) => 1,(3, 1) => 2,(1, 3) => 2,(2, 1) => 1)
Lb = JosephsonCircuits.calcLb(componenttypes,nodeindices,componentvalues,edge2indexdict,Nmodes,Nbranches)
JosephsonCircuits.testshow(stdout,Lb)
# output
sparsevec([1, 2], [1.0e-9, 4.0e-9], 2)
@variables L1 K1 L2 C1
Nmodes = 1
Nbranches = 2
componenttypes = [:L,:K,:L,:C]
nodeindices = [2 0 3 3; 1 0 1 1]
componentvalues = [L1, K1, L2, C1]
componentnamedict = Dict{Symbol, Int}(:C1 => 4,:L2 => 3,:L1 => 1,:K1 => 2)
edge2indexdict = Dict{Tuple{Int, Int}, Int}((1, 2) => 1,(3, 1) => 2,(1, 3) => 2,(2, 1) => 1)
Lb = JosephsonCircuits.calcLb(componenttypes,nodeindices,componentvalues,edge2indexdict,Nmodes,Nbranches)
JosephsonCircuits.testshow(stdout,Lb)
# output
sparsevec([1, 2], Num[L1, L2], 2)
JosephsonCircuits.calcLjb
— MethodcalcLjb(componenttypes, nodeindices, componentvalues, edge2indexdict,
Nmodes, Nbranches)
Calculate the sparse branch Josephson inductance vector whose length is Nbranches*Nmodes
. Note that nodeindices
is "one indexed" so 1 is the ground node.
Examples
Nmodes = 1
Nbranches = 2
componenttypes = [:Lj,:C,:Lj,:C]
nodeindices = [2 3 3 3; 1 2 1 1]
componentvalues = [1e-9, 1e-12, 4e-9, 1e-12]
componentnamedict = Dict{Symbol, Int}(:C2 => 4,:L2 => 3,:L1 => 1,:Cc => 2)
edge2indexdict = Dict{Tuple{Int, Int}, Int}((1, 2) => 1,(3, 1) => 2,(1, 3) => 2,(2, 1) => 1)
Ljb = JosephsonCircuits.calcLjb(componenttypes,nodeindices,componentvalues,edge2indexdict,Nmodes,Nbranches)
JosephsonCircuits.testshow(stdout,Ljb)
# output
sparsevec([1, 2], [1.0e-9, 4.0e-9], 2)
@variables Lj1 K1 Lj2 C1
Nmodes = 1
Nbranches = 2
componenttypes = [:Lj,:K,:Lj,:C]
nodeindices = [2 0 3 3; 1 0 1 1]
componentvalues = [Lj1, K1, Lj2, C1]
componentnamedict = Dict{Symbol, Int}(:C1 => 4,:Lj2 => 3,:Lj1 => 1,:K1 => 2)
edge2indexdict = Dict{Tuple{Int, Int}, Int}((1, 2) => 1,(3, 1) => 2,(1, 3) => 2,(2, 1) => 1)
Ljb = JosephsonCircuits.calcLjb(componenttypes,nodeindices,componentvalues,edge2indexdict,Nmodes,Nbranches)
JosephsonCircuits.testshow(stdout,Ljb)
# output
sparsevec([1, 2], Num[Lj1, Lj2], 2)
JosephsonCircuits.calcLmean
— MethodcalcLmean(componenttypes::Vector{Symbol}, componentvalues::Vector)
Return the mean of the linear and Josephson inductors.
Examples
julia> JosephsonCircuits.calcLmean([:R,:L,:C,:Lj],[10,4,5,1])
2.5
julia> @variables R1 L1 C1 Lj1;JosephsonCircuits.calcLmean([:R,:L,:C,:Lj],[R1, L1, C1, Lj1])
(1//2)*(L1 + Lj1)
JosephsonCircuits.calcLmean_inner
— MethodcalcLmean_inner(componenttypes::Vector, componentvalues::Vector,
valuecomponenttypes::Vector{Nothing})
Return the mean of the linear and Josephson inductors. Return 0 if the expected return type is Nothing.
Examples
julia> JosephsonCircuits.calcLmean_inner([:R,:C,:C,:P],[10,4,5,1],Nothing[])
0
julia> @variables R1 L1 C1 Lj1;JosephsonCircuits.calcLmean_inner([:R,:C,:C,:C],[R1, L1, C1, Lj1],Nothing[])
0
JosephsonCircuits.calcLmean_inner
— MethodcalcLmean_inner(componenttypes::Vector, componentvalues::Vector,
valuecomponenttypes::Vector)
Return the mean of the linear and Josephson inductors.
Examples
julia> JosephsonCircuits.calcLmean_inner([:R,:L,:C,:Lj],[10,4,5,1],Float64[])
2.5
julia> JosephsonCircuits.calcLmean_inner([:R,:C,:C,:C],[10,4,5,1],Float64[])
0.0
julia> @variables R1 L1 C1 Lj1;JosephsonCircuits.calcLmean_inner([:R,:L,:C,:Lj],[R1, L1, C1, Lj1], Num[])
(1//2)*(L1 + Lj1)
JosephsonCircuits.calcMb
— MethodcalcMb(componenttypes::Vector{Symbol}, nodeindices::Matrix{Int},
componentvalues::Vector, componentnamedict::Dict,
mutualinductorbranchnames::Vector, edge2indexdict::Dict, Nmodes,
Nbranches)
Returns the branch mutual inductance matrix. Note that nodeindices
is "one indexed" so 1 is the ground node.
Examples
Nmodes = 1
Nbranches = 2
componenttypes = [:L,:K,:L,:C]
nodeindices = [2 0 3 3; 1 0 1 1]
componentvalues = [1e-9, 0.2, 2e-9, 1e-12]
componentnamedict = Dict{Symbol, Int}(:C2 => 4,:L2 => 3,:L1 => 1,:K1 => 2)
edge2indexdict = Dict{Tuple{Int, Int}, Int}((1, 2) => 1,(3, 1) => 2,(1, 3) => 2,(2, 1) => 1)
mutualinductorbranchnames = [ :L1, :L2]
Mb = JosephsonCircuits.calcMb(componenttypes,nodeindices,componentvalues,componentnamedict,mutualinductorbranchnames,edge2indexdict,Nmodes,Nbranches)
# output
2×2 SparseArrays.SparseMatrixCSC{Float64, Int64} with 2 stored entries:
⋅ 2.82843e-10
2.82843e-10 ⋅
@variables L1 L2 K1 C1
Nmodes = 2
Nbranches = 2
componenttypes = [:L,:K,:L,:C]
nodeindices = [2 0 3 3; 1 0 1 1]
componentvalues = [L1, K1, L2, C1]
componentnamedict = Dict{Symbol, Int}(:C1 => 4,:L2 => 3,:L1 => 1,:K1 => 2)
edge2indexdict = Dict{Tuple{Int, Int}, Int}((1, 2) => 1,(3, 1) => 2,(1, 3) => 2,(2, 1) => 1)
mutualinductorbranchnames = [ :L1, :L2]
Mb = JosephsonCircuits.calcMb(componenttypes,nodeindices,componentvalues,componentnamedict,mutualinductorbranchnames,edge2indexdict,Nmodes,Nbranches)
# output
4×4 SparseArrays.SparseMatrixCSC{Num, Int64} with 4 stored entries:
⋅ ⋅ K1*sqrt(L1*L2) ⋅
⋅ ⋅ ⋅ K1*sqrt(L1*L2)
K1*sqrt(L1*L2) ⋅ ⋅ ⋅
⋅ K1*sqrt(L1*L2) ⋅ ⋅
JosephsonCircuits.calcVb
— MethodcalcVb(componenttypes::Vector{Symbol}, nodeindices::Matrix{Int},
componentvalues::Vector, edge2indexdict::Dict, Nmodes, Nbranches)
Calculate the sparse branch voltage source vector whose length is Nbranches*Nmodes
. Note that nodeindices
is "one indexed" so 1 is the ground node.
Examples
Nmodes = 1
Nbranches = 2
componenttypes = [:V,:C,:L1,:C]
nodeindices = [2 0 3 3; 1 0 1 1]
componentvalues = [1e-9, 0.2, 4e-9, 1e-12]
componentnamedict = Dict{Symbol, Int}(:C2 => 4,:L1 => 3,:V1 => 1,:C1 => 2)
edge2indexdict = Dict{Tuple{Int, Int}, Int}((1, 2) => 1,(3, 1) => 2,(1, 3) => 2,(2, 1) => 1)
Vb = JosephsonCircuits.calcVb(componenttypes,nodeindices,componentvalues,edge2indexdict,Nmodes,Nbranches)
JosephsonCircuits.testshow(stdout,Vb)
# output
sparsevec([1], [1.0e-9], 2)
@variables V1 C1 L1 C2
Nmodes = 1
Nbranches = 2
componenttypes = [:V,:C,:L,:C]
nodeindices = [2 0 3 3; 1 0 1 1]
componentvalues = [V1, C1, L1, C2]
componentnamedict = Dict{Symbol, Int}(:C2 => 4,:L1 => 3,:V1 => 1,:C1 => 2)
edge2indexdict = Dict{Tuple{Int, Int}, Int}((1, 2) => 1,(3, 1) => 2,(1, 3) => 2,(2, 1) => 1)
Vb = JosephsonCircuits.calcVb(componenttypes,nodeindices,componentvalues,edge2indexdict,Nmodes,Nbranches)
JosephsonCircuits.testshow(stdout,Vb)
# output
sparsevec([1], Num[V1], 2)
JosephsonCircuits.calcbranchvector
— Methodcalcbranchvector(componenttypes::Vector{Symbol},
nodeindices::Matrix{Int}, componentvalues::Vector,
valuecomponenttypes::Vector, edge2indexdict::Dict, Nmodes, Nbranches,
component::Symbol, combine::Function)
Calculate the sparse branch vector whose length is Nbranches*Nmodes
for the given component symbol. Note that nodeindices
is "one indexed" so 1 is the ground node. The combine
function determines how elements of the sparse vector will be combined.
JosephsonCircuits.calccircuitgraph
— Methodcalccircuitgraph(parsedsortedcircuit::ParsedSortedCircuit)
Calculate the superconducting spanning tree, incidence matrix, closure branches, and loops from the parsed and sorted circuit.
See also CircuitGraph
, calcgraphs
, and extractbranches
for more explanation.
Examples
@variables Ipump Rleft L1 K1 L2 C2
psc = JosephsonCircuits.ParsedSortedCircuit(
[2 2 2 2 0 3 3; 1 1 1 1 0 1 1],
["0", "1", "2"],
["L1", "L2"],
["P1", "I1", "R1", "L1", "K1", "L2", "C2"],
[:P, :I, :R, :L, :K, :L, :C],
Num[1, Ipump, Rleft, L1, K1, L2, C2],
Dict("L1" => 4, "I1" => 2, "L2" => 6, "C2" => 7, "R1" => 3, "P1" => 1, "K1" => 5),
3)
cg = JosephsonCircuits.calccircuitgraph(psc)
# output
JosephsonCircuits.CircuitGraph(Dict((1, 2) => 1, (3, 1) => 2, (1, 3) => 2, (2, 1) => 1), sparse([1, 2], [1, 2], [1, 1], 2, 2), [(1, 2), (1, 3)], Tuple{Int64, Int64}[], [(1, 2), (1, 3)], Vector{Int64}[], Int64[], Graphs.SimpleGraphs.SimpleGraph{Int64}(2, [[2, 3], [1], [1]]), 2)
@variables Ipump Rleft L Lj Cj
circuit = Tuple{String,String,String,Num}[]
push!(circuit,("P1","1","0",1))
push!(circuit,("I1","1","0",Ipump))
push!(circuit,("R1","1","0",Rleft))
push!(circuit,("L1","1","2",L))
push!(circuit,("Lj1","2","0",Lj))
push!(circuit,("C2","2","0",Cj))
psc = JosephsonCircuits.parsesortcircuit(circuit)
cg = JosephsonCircuits.calccircuitgraph(psc)
# output
JosephsonCircuits.CircuitGraph(Dict((3, 2) => 3, (1, 2) => 1, (3, 1) => 2, (1, 3) => 2, (2, 1) => 1, (2, 3) => 3), sparse([1, 3, 2, 3], [1, 1, 2, 2], [1, -1, 1, 1], 3, 2), [(1, 2), (1, 3)], [(3, 2)], [(1, 2), (1, 3), (2, 3)], [[1, 2, 3]], Int64[], Graphs.SimpleGraphs.SimpleGraph{Int64}(3, [[2, 3], [1, 3], [1, 2]]), 3)
JosephsonCircuits.calccm!
— Methodcalccm!(cm, S, Snoise, w)
Calculate the bosonic commutation relations for a scattering matrix S in the field ladder operator basis. Overwrites cm with output.
Examples
julia> @variables a b c d an bn cn dn;cm = Num[0, 0];JosephsonCircuits.calccm!(cm,Num[a b; c d],[an bn; cn dn],[1, -1]);cm
2-element Vector{Num}:
abs2(an) + abs2(a) - abs2(b) - abs2(bn)
abs2(c) + abs2(cn) - abs2(d) - abs2(dn)
JosephsonCircuits.calccm!
— Methodcalccm!(cm, S, w)
Calculate the bosonic commutation relations for a scattering matrix S in the field ladder operator basis. Overwrites cm with output.
Examples
julia> @variables a b;cm=Num[0,0];JosephsonCircuits.calccm!(cm,[a b; b a],[-1,1]);cm
2-element Vector{Num}:
-abs2(a) + abs2(b)
abs2(a) - abs2(b)
JosephsonCircuits.calccm!
— Methodcalccm!(cm, S, Snoise, w)
Calculate the bosonic commutation relations for a scattering matrix S in the field ladder operator basis. Overwrites cm with output. Use a compensated sum to reduce floating point errors.
Examples
julia> cm=Float64[0, 0];JosephsonCircuits.calccm!(cm,[1 2;3 4],[1 2 3 4;5 6 7 8],[-1,1]);cm
2-element Vector{Float64}:
13.0
33.0
JosephsonCircuits.calccm!
— Methodcalccm!(cm, S, w)
Calculate the bosonic commutation relations for a scattering matrix S in the field ladder operator basis. Overwrites cm with output. Use a compensated sum to reduce floating point errors.
Examples
julia> cm=Float64[0,0];JosephsonCircuits.calccm!(cm,[3/5 4/5;4/5 3/5],[-1,1]);cm
2-element Vector{Float64}:
0.28000000000000014
-0.28000000000000014
JosephsonCircuits.calccm
— Methodcalccm(S, Snoise, w)
Calculate the bosonic commutation relations for a scattering matrix S in the field ladder operator basis. Sum the abs2 of each element along the horizontal axis, applying a minus sign if the corresponding frequency is negative. Represents energy conservation.
Examples
julia> JosephsonCircuits.calccm([1 1e-100 2e-100 1;1 1 1 1],[1 1e-100 2e-100 1;1 1 1 1],[1, -1])
2-element Vector{Float64}:
6.0e-200
0.0
julia> JosephsonCircuits.calccm(Complex{Float64}[1 1e-100 2e-100 1;1 1 1 1],Complex{Float64}[1 1e-100 2e-100 1;1 1 1 1],[1, -1])
2-element Vector{Float64}:
6.0e-200
0.0
julia> @variables a b c d an bn cn dn;JosephsonCircuits.calccm([a b; c d],[an bn; cn dn],[1, -1])
2-element Vector{Num}:
abs2(an) + abs2(a) - abs2(b) - abs2(bn)
abs2(c) + abs2(cn) - abs2(d) - abs2(dn)
JosephsonCircuits.calccm
— Methodcalccm(S, w)
Calculate the bosonic commutation relations for a scattering matrix S in the field ladder operator basis. Sum the abs2 of each element along the horizontal axis, applying a minus sign if the corresponding frequency is negative. Represents energy conservation.
Examples
julia> JosephsonCircuits.calccm(Complex{Float64}[3/5 4/5;4/5 3/5],[1])
2-element Vector{Float64}:
1.0
1.0
julia> JosephsonCircuits.calccm([1 1e-100 2e-100 1;1 0 0 1],[1, -1])
2-element Vector{Float64}:
3.0e-200
0.0
julia> @variables a b;JosephsonCircuits.calccm([a b; b a],[1, -1])
2-element Vector{Num}:
abs2(a) - abs2(b)
-abs2(a) + abs2(b)
JosephsonCircuits.calcdZdroZ2
— MethodcalcdZdroZ2(sensitivityindices, componenttypes, componentvalues, wmodes,
symfreqvar)
Calculate 1/Z^2 times the derivative of Z with respect to parameter scaling the value of the circuit component. For example:
Zc = 1/(im*w*Cg*r)
1/Zc^2*dZc/dr|_{r=1} = -im*Cg*w
Zl = im*w*Lj*r
1/Zl^2*dZl/dr =1/(im*Lj*r^2*w)|_{r=1} = 1/(im*Lj*w)
Zr = R*r
1/Zr^2*dZr/dr|_{r=1} = 1/(r^2*R) = 1/R
Examples
julia> JosephsonCircuits.calcdZdroZ2([1],[:R], [50.0], [1.0],nothing)
1-element Vector{ComplexF64}:
0.02 + 0.0im
julia> JosephsonCircuits.calcdZdroZ2([1],[:C], [2.0], [1.0],nothing)
1-element Vector{ComplexF64}:
0.0 - 2.0im
julia> JosephsonCircuits.calcdZdroZ2([1],[:L], [2.0], [1.0],nothing)
1-element Vector{ComplexF64}:
0.0 - 0.5im
JosephsonCircuits.calcfj!
— Methodcalcfj!(F,J,nodeflux,wmodesm,wmodes2m,Rbnm,invLnm,Cnm,Gnm,bm,Ljb,Ljbindices,
Ljbindicesm,Nmodes,Lmean,AoLjbm)
Calculate the residual and the Jacobian. These are calculated with one function in order to reuse the time domain nonlinearity calculation.
Leave off the type signatures on F and J because the solver will pass a type of Nothing if it only wants to calculate F or J.
JosephsonCircuits.calcfj2!
— Methodcalcfj2!(F,J,phin,wmodesm,wmodes2m,Rbnm,invLnm,Cnm,Gnm,bm,Ljb,Ljbindices,
Ljbindicesm,Nmodes,Lmean,AoLjbm)
Calculate the residual and the Jacobian. These are calculated with one function in order to reuse as much as possible.
Leave off the type signatures on F and J because the solver will pass nothing
if it only wants to calculate F or J.
JosephsonCircuits.calcfreqs
— Methodcalcfreqs(Nharmonics::NTuple{N,Int}, Nw::NTuple{N,Int}, Nt::NTuple{N,Int})
Calculate the dimensions of the DFT or RFDT in the frequency domain and the time domain given a tuple of the number of harmonics. Eg. 0,w,2w,3w would be 3 harmonics. Also calculate the possible modes and their coordinates in the frequency domain RDFT array. See also calcfreqsrdft
and calcfreqsdft
.
JosephsonCircuits.calcfreqsdft
— Methodcalcfreqsdft(Nharmonics::NTuple{N,Int})
Calculate the dimensions of the DFT in the frequency domain and the time domain given a tuple of the number of harmonics. Eg. 0,w,2w,3w would be 3 harmonics. Also calculate the possible modes and their coordinates in the frequency domain DFT array.
Arguments
Nharmonics
: is a tuple of the number of harmonics to calculate for each frequency.
Returns
Frequencies
: A simple structure to hold time and frequency domain information for the signal for a single node. SeeFrequencies
.
Examples
julia> JosephsonCircuits.calcfreqsrdft((1,))
JosephsonCircuits.Frequencies{1}((1,), (2,), (3,), CartesianIndex{1}[CartesianIndex(1,), CartesianIndex(2,)], [(0,), (1,)])
julia> JosephsonCircuits.calcfreqsrdft((2,))
JosephsonCircuits.Frequencies{1}((2,), (3,), (4,), CartesianIndex{1}[CartesianIndex(1,), CartesianIndex(2,), CartesianIndex(3,)], [(0,), (1,), (2,)])
julia> JosephsonCircuits.calcfreqsrdft((3,))
JosephsonCircuits.Frequencies{1}((3,), (4,), (6,), CartesianIndex{1}[CartesianIndex(1,), CartesianIndex(2,), CartesianIndex(3,), CartesianIndex(4,)], [(0,), (1,), (2,), (3,)])
julia> JosephsonCircuits.calcfreqsrdft((3,3))
JosephsonCircuits.Frequencies{2}((3, 3), (4, 7), (6, 7), CartesianIndex{2}[CartesianIndex(1, 1), CartesianIndex(2, 1), CartesianIndex(3, 1), CartesianIndex(4, 1), CartesianIndex(1, 2), CartesianIndex(2, 2), CartesianIndex(3, 2), CartesianIndex(4, 2), CartesianIndex(1, 3), CartesianIndex(2, 3) … CartesianIndex(3, 5), CartesianIndex(4, 5), CartesianIndex(1, 6), CartesianIndex(2, 6), CartesianIndex(3, 6), CartesianIndex(4, 6), CartesianIndex(1, 7), CartesianIndex(2, 7), CartesianIndex(3, 7), CartesianIndex(4, 7)], [(0, 0), (1, 0), (2, 0), (3, 0), (0, 1), (1, 1), (2, 1), (3, 1), (0, 2), (1, 2) … (2, -3), (3, -3), (0, -2), (1, -2), (2, -2), (3, -2), (0, -1), (1, -1), (2, -1), (3, -1)])
JosephsonCircuits.calcfreqsrdft
— Methodcalcfreqsrdft(Nharmonics::NTuple{N,Int})
Calculate the dimensions of the RDFT in the frequency domain and the time domain given a tuple of the number of harmonics. Eg. 0,w,2w,3w would be 3 harmonics. Also calculate the possible modes and their coordinates in the frequency domain RDFT array.
Arguments
Nharmonics
: is a tuple of the number of harmonics to calculate for each frequency.
Returns
Frequencies
: A simple structure to hold time and frequency domain information for the signal for a single node. SeeFrequencies
.
Examples
julia> JosephsonCircuits.calcfreqsrdft((1,))
JosephsonCircuits.Frequencies{1}((1,), (2,), (3,), CartesianIndex{1}[CartesianIndex(1,), CartesianIndex(2,)], [(0,), (1,)])
julia> JosephsonCircuits.calcfreqsrdft((2,))
JosephsonCircuits.Frequencies{1}((2,), (3,), (4,), CartesianIndex{1}[CartesianIndex(1,), CartesianIndex(2,), CartesianIndex(3,)], [(0,), (1,), (2,)])
julia> JosephsonCircuits.calcfreqsrdft((3,))
JosephsonCircuits.Frequencies{1}((3,), (4,), (6,), CartesianIndex{1}[CartesianIndex(1,), CartesianIndex(2,), CartesianIndex(3,), CartesianIndex(4,)], [(0,), (1,), (2,), (3,)])
julia> JosephsonCircuits.calcfreqsrdft((3,3))
JosephsonCircuits.Frequencies{2}((3, 3), (4, 7), (6, 7), CartesianIndex{2}[CartesianIndex(1, 1), CartesianIndex(2, 1), CartesianIndex(3, 1), CartesianIndex(4, 1), CartesianIndex(1, 2), CartesianIndex(2, 2), CartesianIndex(3, 2), CartesianIndex(4, 2), CartesianIndex(1, 3), CartesianIndex(2, 3) … CartesianIndex(3, 5), CartesianIndex(4, 5), CartesianIndex(1, 6), CartesianIndex(2, 6), CartesianIndex(3, 6), CartesianIndex(4, 6), CartesianIndex(1, 7), CartesianIndex(2, 7), CartesianIndex(3, 7), CartesianIndex(4, 7)], [(0, 0), (1, 0), (2, 0), (3, 0), (0, 1), (1, 1), (2, 1), (3, 1), (0, 2), (1, 2) … (2, -3), (3, -3), (0, -2), (1, -2), (2, -2), (3, -2), (0, -1), (1, -1), (2, -1), (3, -1)])
JosephsonCircuits.calcgraphs
— Methodcalcgraphs(Ledgearray::Array{Tuple{Int, Int}, 1}, Nnodes::Int)
Calculate the superconducting spanning tree, closure branches, and loops. Accepts the graph of linear inductors and Josephson junctions. Outputs lists of edges that can be used to generate graphs.
Examples
julia> JosephsonCircuits.calcgraphs([(2, 1), (2, 1), (2, 1), (3, 1)], 3)
JosephsonCircuits.CircuitGraph(Dict((1, 2) => 1, (3, 1) => 2, (1, 3) => 2, (2, 1) => 1), sparse([1, 2], [1, 2], [1, 1], 2, 2), [(1, 2), (1, 3)], Tuple{Int64, Int64}[], [(1, 2), (1, 3)], Vector{Int64}[], Int64[], Graphs.SimpleGraphs.SimpleGraph{Int64}(2, [[2, 3], [1], [1]]), 2)
julia> JosephsonCircuits.calcgraphs([(4, 3), (3, 6), (5, 3), (3, 7), (2, 4), (6, 8), (2, 5), (8, 7), (2, 8)], 8)
JosephsonCircuits.CircuitGraph(Dict((6, 8) => 8, (2, 5) => 2, (3, 7) => 7, (6, 3) => 6, (7, 8) => 9, (3, 4) => 4, (7, 3) => 7, (2, 8) => 3, (4, 2) => 1, (8, 6) => 8…), sparse([1, 2, 3, 4, 5, 6, 7, 1, 4, 2, 5, 6, 8, 7, 9, 3, 8, 9], [1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 7], [-1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1], 9, 7), [(2, 4), (2, 5), (2, 8), (3, 4), (3, 6), (3, 7)], [(5, 3), (8, 6), (8, 7)], [(2, 4), (2, 5), (2, 8), (3, 4), (3, 5), (3, 6), (3, 7), (6, 8), (7, 8)], [[2, 4, 3, 5], [2, 4, 3, 6, 8], [2, 4, 3, 7, 8]], [1], Graphs.SimpleGraphs.SimpleGraph{Int64}(9, [Int64[], [4, 5, 8], [4, 5, 6, 7], [2, 3], [2, 3], [3, 8], [3, 8], [2, 6, 7]]), 9)
julia> JosephsonCircuits.calcgraphs([(2, 1), (2, 1), (3, 1)],4)
JosephsonCircuits.CircuitGraph(Dict((1, 2) => 1, (3, 1) => 2, (1, 3) => 2, (2, 1) => 1), sparse([1, 2], [1, 2], [1, 1], 2, 3), [(1, 2), (1, 3)], Tuple{Int64, Int64}[], [(1, 2), (1, 3)], Vector{Int64}[], Int64[], Graphs.SimpleGraphs.SimpleGraph{Int64}(2, [[2, 3], [1], [1]]), 2)
JosephsonCircuits.calcimpedance
— Methodcalcimpedance(c, type, w, symfreqvar)
Examples
julia> @variables w;JosephsonCircuits.calcimpedance(30*w,:R,2.0,w)
60.0 + 0.0im
julia> @variables w;JosephsonCircuits.calcimpedance(30*w,:C,2.0,w)
0.0 - 0.008333333333333333im
julia> @variables w;JosephsonCircuits.calcimpedance(30*w,:L,2.0,w)
0.0 + 120.0im
julia> @variables w;JosephsonCircuits.calcimpedance(30*w,:R,-2.0,w)
-60.0 + 0.0im
julia> @variables w;JosephsonCircuits.calcimpedance(30*w,:C,-2.0,w)
0.0 - 0.008333333333333333im
julia> @variables w;JosephsonCircuits.calcimpedance(30*w,:L,-2.0,w)
0.0 + 120.0im
JosephsonCircuits.calcimpedance
— Methodcalcimpedance(c::Union{Integer,T,Complex{T}}, type, w, symfreqvar,
) where {T<:AbstractFloat}
Examples
julia> JosephsonCircuits.calcimpedance(30.0,:C,1.0,nothing)
0.0 - 0.03333333333333333im
julia> JosephsonCircuits.calcimpedance(30.0,:L,1.0,nothing)
0.0 + 30.0im
julia> JosephsonCircuits.calcimpedance(30.0,:R,1.0,nothing)
30.0 + 0.0im
julia> JosephsonCircuits.calcimpedance(30.0,:C,-1.0,nothing)
-0.0 + 0.03333333333333333im
julia> JosephsonCircuits.calcimpedance(30.0,:L,-1.0,nothing)
-0.0 - 30.0im
julia> JosephsonCircuits.calcimpedance(30.0,:R,-1.0,nothing)
30.0 + 0.0im
JosephsonCircuits.calcindexdict
— Methodcalcindexdict(N::Int)
Return a dictionary of Cartesian indices where the Cartesian index is the key and the index giving the order is the value.
Examples
julia> JosephsonCircuits.calcindexdict(3)
Dict{CartesianIndex{1}, Int64} with 3 entries:
CartesianIndex(2,) => 2
CartesianIndex(3,) => 3
CartesianIndex(1,) => 1
JosephsonCircuits.calcindexdict
— Methodcalcindexdict(N::Tuple)
Return a dictionary of Cartesian indices where the Cartesian index is the key and the index giving the order is the value.
Examples
julia> JosephsonCircuits.calcindexdict((2,3))
Dict{CartesianIndex{2}, Int64} with 6 entries:
CartesianIndex(2, 3) => 6
CartesianIndex(2, 1) => 2
CartesianIndex(1, 3) => 5
CartesianIndex(1, 1) => 1
CartesianIndex(2, 2) => 4
CartesianIndex(1, 2) => 3
JosephsonCircuits.calcindices
— Methodcalcindices(m::Integer)
The indices over which to calculate the idlers using the formula ws+2iwp where i is an index. This could be defined differently without causing any issues.
Examples
julia> JosephsonCircuits.calcindices(7)
-3:3
julia> JosephsonCircuits.calcindices(8)
-4:3
JosephsonCircuits.calcinputcurrentoutputvoltage!
— Methodcalcinputcurrentoutputvoltage!(inputcurrent, outputvoltage, nodeflux,
bnm, inputportindices, outputportindices, nodeindices, wmodes)
Calculate the elements of the Z matrix.
Examples
inputwave = JosephsonCircuits.LinearAlgebra.Diagonal(ComplexF64[0])
outputwave = ComplexF64[0;;]
bnm = ComplexF64[-1; 1;;]
portimpedanceindices = [2]
portimpedances = ComplexF64[50.0 + 0.0im]
nodeindices = [2 2 2 2 3; 3 3 1 1 1]
componenttypes = [:P, :R, :L, :C, :C]
wmodes = [1]
phin = ComplexF64[-50/(im*wmodes[1]);50/(im*wmodes[1]);;]
symfreqvar = nothing
JosephsonCircuits.calcinputcurrentoutputvoltage!(inputwave,outputwave,phin,bnm,portimpedanceindices,
portimpedanceindices,nodeindices,wmodes)
println(outputwave)
# output
ComplexF64[-100.0 + 0.0im;;]
JosephsonCircuits.calcinputoutput!
— Methodcalcinputoutput!(inputwave, outputwave, phin, bnm, inputportindices,
outputportindices, inputportimpedances, outputportimpedances,
nodeindices, componenttypes, wmodes, symfreqvar)
Return the input and output waves for the system linearized around the strong pump.
Examples
inputwave = JosephsonCircuits.LinearAlgebra.Diagonal(ComplexF64[0])
outputwave = ComplexF64[0;;]
bnm = ComplexF64[1; 0;;]
portimpedanceindices = [3]
portimpedances = ComplexF64[50]
nodeindices = [2 2 2 2 0 3 3; 1 1 1 1 0 1 1]
componenttypes = [:P, :I, :R, :L, :K, :L, :C]
wmodes = [1]
phin = ComplexF64[0;0;;]
symfreqvar = nothing
JosephsonCircuits.calcinputoutput!(inputwave,outputwave,phin,bnm,portimpedanceindices,
portimpedanceindices,portimpedances,portimpedances,nodeindices,componenttypes,
wmodes,symfreqvar)
println(outputwave)
# output
ComplexF64[-3.5355339059327378 + 0.0im;;]
inputwave = JosephsonCircuits.LinearAlgebra.Diagonal(ComplexF64[0])
outputwave = ComplexF64[0;;]
bnm = ComplexF64[1; 0;;]
portimpedanceindices = [3]
portimpedances = ComplexF64[50]
nodeindices = [2 2 2 2 0 3 3; 1 1 1 1 0 1 1]
componenttypes = [:P, :I, :R, :L, :K, :L, :C]
wmodes = [1]
phin = ComplexF64[50/(im*wmodes[1]);0;;]
symfreqvar = nothing
JosephsonCircuits.calcinputoutput!(inputwave,outputwave,phin,bnm,portimpedanceindices,
portimpedanceindices,portimpedances,portimpedances,nodeindices,componenttypes,
wmodes,symfreqvar)
println(outputwave)
# output
ComplexF64[3.5355339059327378 + 0.0im;;]
inputwave = JosephsonCircuits.LinearAlgebra.Diagonal(ComplexF64[0])
outputwave = ComplexF64[0;;]
bnm = ComplexF64[1; 0;;]
portimpedanceindices = [3]
portimpedances = ComplexF64[50]
nodeindices = [1 1 1 1 0 1 1; 2 2 2 2 0 3 3;]
componenttypes = [:P, :I, :R, :L, :K, :L, :C]
wmodes = [1]
phin = ComplexF64[50/(im*wmodes[1]);0;;]
symfreqvar = nothing
JosephsonCircuits.calcinputoutput!(inputwave,outputwave,phin,bnm,portimpedanceindices,
portimpedanceindices,portimpedances,portimpedances,nodeindices,componenttypes,
wmodes,symfreqvar)
println(outputwave)
# output
ComplexF64[-3.5355339059327378 + 0.0im;;]
inputwave = JosephsonCircuits.LinearAlgebra.Diagonal(ComplexF64[0])
outputwave = ComplexF64[0;;]
bnm = ComplexF64[-1; 1;;]
portimpedanceindices = [2]
portimpedances = ComplexF64[50.0 + 0.0im]
nodeindices = [2 2 2 2 3; 3 3 1 1 1]
componenttypes = [:P, :R, :L, :C, :C]
wmodes = [1]
phin = ComplexF64[0;0;;]
symfreqvar = nothing
JosephsonCircuits.calcinputoutput!(inputwave,outputwave,phin,bnm,portimpedanceindices,
portimpedanceindices,portimpedances,portimpedances,nodeindices,componenttypes,
wmodes,symfreqvar)
println(outputwave)
# output
ComplexF64[3.5355339059327378 + 0.0im;;]
inputwave = JosephsonCircuits.LinearAlgebra.Diagonal(ComplexF64[0])
outputwave = ComplexF64[0;;]
bnm = ComplexF64[-1; 1;;]
portimpedanceindices = [2]
portimpedances = ComplexF64[50.0 + 0.0im]
nodeindices = [2 2 2 2 3; 3 3 1 1 1]
componenttypes = [:P, :R, :L, :C, :C]
wmodes = [1]
phin = ComplexF64[-50/(im*wmodes[1]);50/(im*wmodes[1]);;]
symfreqvar = nothing
JosephsonCircuits.calcinputoutput!(inputwave,outputwave,phin,bnm,portimpedanceindices,
portimpedanceindices,portimpedances,portimpedances,nodeindices,componenttypes,
wmodes,symfreqvar)
println(outputwave)
# output
ComplexF64[-10.606601717798213 + 0.0im;;]
JosephsonCircuits.calcinputoutput_inner!
— Methodcalcinputoutput_inner!(inputwave, outputwave, phin, bnm, inputportindices,
outputportindices, inputportimpedances, outputportimpedances,
nodeindices, componenttypes, wmodes, symfreqvar, nosource)
Calculate the input and output power waves as defined in (except in units of sqrt(photons/second) instead of sqrt(power) K. Kurokawa, "Power Waves and the Scattering Matrix", IEEE Trans. Micr. Theory and Tech. 13, 194–202 (1965) doi: 10.1109/TMTT.1965.1125964 inputwave[(i-1)Nmodes+j,k] = 1/2kval * (portvoltage + portimpedance * portcurrent) we can simplify the above to: inputwave[(i-1)Nmodes+j,k] = 1/2kval * portimpedance * sourcecurrent outputwave[(i-1)Nmodes+j,k] = 1/2kval * (portvoltage - conj(portimpedance) * portcurrent) .
JosephsonCircuits.calcinputoutputnoise!
— Methodcalcinputoutputnoise!(S, inputwave, outputwave, phin, bnm,
inputportindices, outputportindices, inputportimpedances,
outputportimpedances, nodeindices, componenttypes, wmodes, symfreqvar)
Return the input and output waves for the system linearized around the strong pump.
This is a bit of a hack but I ran into issues with complex capacitance when the capacitor was at the same branch as a current source. The calcS function would use that current source in calculating the output waves, which it should not do.
Examples
inputwave = JosephsonCircuits.LinearAlgebra.Diagonal(ComplexF64[0])
noiseoutputwave = ComplexF64[0;;]
phin = ComplexF64[-2.5000000000007394e-10 - 0.000795774715459398im; 1.983790476804266e-20 + 3.141592641138603e-16im;;]
bnm = ComplexF64[1.0 + 0.0im; 0.0 + 0.0im;;]
portimpedanceindices = [2]
noiseportimpedanceindices = [6]
portimpedances = [50]
noiseportimpedances = [1]
nodeindices = [2 2 2 3 3 3; 1 1 3 1 1 1]
componenttypes = [:P, :R, :C, :Lj, :C, :R]
wmodes = [2*pi*5e9]
symfreqvar = nothing
JosephsonCircuits.calcinputoutputnoise!(inputwave,noiseoutputwave,
phin,bnm,portimpedanceindices,noiseportimpedanceindices,
portimpedances,noiseportimpedances,nodeindices,
componenttypes,wmodes,symfreqvar)
println(noiseoutputwave)
# output
ComplexF64[-5.568327974762547e-11 + 3.516177070001411e-15im;;]
JosephsonCircuits.calcinvLn
— MethodcalcinvLn(Lb::SparseVector, Rbn::SparseMatrixCSC, Nmodes)
Returns the nodal inverse inductance matrix. Accepts the vector of branch inductances Lb
and the incidence matrix Rbn
.
Examples
Nmodes = 1
Lb = JosephsonCircuits.SparseArrays.sparsevec([1,2],[1e-9,4e-9])
Rbn = JosephsonCircuits.SparseArrays.sparse([1,2], [1,2], [1,1])
JosephsonCircuits.calcinvLn(Lb,Rbn,Nmodes)
# output
2×2 SparseArrays.SparseMatrixCSC{Float64, Int64} with 2 stored entries:
1.0e9 ⋅
⋅ 2.5e8
@variables L1 L2
Nmodes = 1
Lb = JosephsonCircuits.SparseArrays.sparsevec([1,2],[L1,L2])
Rbn = JosephsonCircuits.SparseArrays.sparse([1,2], [1,2], [1,1])
JosephsonCircuits.calcinvLn(Lb,Rbn,Nmodes)
# output
2×2 SparseArrays.SparseMatrixCSC{Num, Int64} with 2 stored entries:
1 / L1 ⋅
⋅ 1 / L2
@variables L1 L2
Nmodes = 2
Lb = JosephsonCircuits.SparseArrays.sparsevec([1,2],[L1,L2])
Rbn = JosephsonCircuits.SparseArrays.sparse([1,2], [1,2], [1,1])
JosephsonCircuits.calcinvLn(Lb,Rbn,Nmodes)
# output
4×4 SparseArrays.SparseMatrixCSC{Num, Int64} with 4 stored entries:
1 / L1 ⋅ ⋅ ⋅
⋅ 1 / L1 ⋅ ⋅
⋅ ⋅ 1 / L2 ⋅
⋅ ⋅ ⋅ 1 / L2
Nmodes = 1
Lb = JosephsonCircuits.SparseArrays.sparsevec([],Nothing[])
Rbn = JosephsonCircuits.SparseArrays.sparse([1,2], [1,2], [1,1])
JosephsonCircuits.calcinvLn(Lb,Rbn,Nmodes).nzval
# output
Nothing[]
```jldoctest @syms L1 L2 Nmodes = 1 Lb = JosephsonCircuits.SparseArrays.sparsevec([1,2],[L1,L2]) Rbn = JosephsonCircuits.SparseArrays.sparse([1,2], [1,2], [1,1]) JosephsonCircuits.calcinvLn(Lb,Rbn,Nmodes).nzval
output
2-element Vector{Any}: 1 / L1 1 / L2
JosephsonCircuits.calcinvLn
— MethodcalcinvLn(Lb::SparseVector, Mb::SparseMatrixCSC,
Rbn::SparseMatrixCSC, Nmodes)
Returns the nodal inverse inductance matrix. Accepts the vector of branch inductances Lb
, the branch mutual inductance matrix Mb
, and the incidence matrix Rbn
.
Using ldiv instead of an inverse: (where the extra div is an escape sequence) Can solve A x = B with: x = A \ B or x = invA * B, so we can perform the inverse here with: s = RbnT * invL * Rbn or s = RbnT * (L \ Rbn), the latter of which should be faster and more numerically stable.
Examples
Nmodes = 2
Lb = JosephsonCircuits.SparseArrays.sparsevec([1,2],[1e-9,4e-9])
Mb = JosephsonCircuits.SparseArrays.sparse([2,1], [1,2], [4e-10,4e-10])
Rbn = JosephsonCircuits.SparseArrays.sparse([1,2], [1,2], [1,1])
JosephsonCircuits.calcinvLn(Lb,Mb,Rbn,Nmodes)
# output
4×4 SparseArrays.SparseMatrixCSC{Float64, Int64} with 8 stored entries:
1.04167e9 ⋅ -1.04167e8 ⋅
⋅ 1.04167e9 ⋅ -1.04167e8
-1.04167e8 ⋅ 2.60417e8 ⋅
⋅ -1.04167e8 ⋅ 2.60417e8
@variables L1 L2 Lm
Nmodes = 1
Lb = JosephsonCircuits.SparseArrays.sparsevec([1,2],[L1,L2]);
Mb = JosephsonCircuits.SparseArrays.sparse([2,1], [1,2], [Lm,Lm]);
Rbn = JosephsonCircuits.SparseArrays.sparse([1,2], [1,2], [1.0,1.0])
println(JosephsonCircuits.calcinvLn(Lb,Mb,Rbn,Nmodes))
# output
sparse([1, 2, 1, 2], [1, 1, 2, 2], Num[(1.0 + (Lm*(Lm / L1)) / (L2 + (-(Lm^2)) / L1)) / L1, (-(Lm / L1)) / (L2 + (-(Lm^2)) / L1), (-(Lm / (L2 + (-(Lm^2)) / L1))) / L1, 1.0 / (L2 + (-(Lm^2)) / L1)], 2, 2)
@variables L1 L2
Nmodes = 1
Lb = JosephsonCircuits.SparseArrays.sparsevec([1,2],[L1,L2]);
Mb = JosephsonCircuits.SparseArrays.sparse([], [], Nothing[]);
Rbn = JosephsonCircuits.SparseArrays.sparse([1,2], [1,2], [1,1])
println(JosephsonCircuits.calcinvLn(Lb,Mb,Rbn,Nmodes))
# output
sparse([1, 2], [1, 2], Num[1 / L1, 1 / L2], 2, 2)
@syms L1 L2 Lm
Nmodes = 1
Lb = JosephsonCircuits.SparseArrays.sparsevec([1,2],[L1,L2]);
Mb = JosephsonCircuits.SparseArrays.sparse([2,1], [1,2], [Lm,Lm]);
Rbn = JosephsonCircuits.SparseArrays.sparse([1,2], [1,2], [1.0,1.0])
println(JosephsonCircuits.calcinvLn(Lb,Mb,Rbn,Nmodes))
# output
sparse([1, 2, 1, 2], [1, 1, 2, 2], Num[(1.0 + (Lm*(Lm / L1)) / (L2 + (-(Lm^2)) / L1)) / L1, (-(Lm / L1)) / (L2 + (-(Lm^2)) / L1), (-(Lm / (L2 + (-(Lm^2)) / L1))) / L1, 1.0 / (L2 + (-(Lm^2)) / L1)], 2, 2)
JosephsonCircuits.calcmodefreqs
— Methodcalcmodefreqs(w::NTuple{N},modes::Vector{NTuple{N,Int}})
Calculate the frequencies of the modes given a tuple of fundamental frequencies and a vector of tuples containing the mixing products and harmonics.
Examples
julia> @variables wp1 wp2;JosephsonCircuits.calcmodefreqs((wp1, wp2),[(0, 0), (1, 0), (2, 0), (0, 1), (1, 1), (2, 1)])
6-element Vector{Num}:
0
wp1
2wp1
wp2
wp1 + wp2
2wp1 + wp2
julia> JosephsonCircuits.calcmodefreqs((1., 1.1),[(0, 0), (1, 0), (2, 0), (0, 1), (1, 1), (2, 1)])
6-element Vector{Float64}:
0.0
1.0
2.0
1.1
2.1
3.1
JosephsonCircuits.calcnodematrix
— Methodcalcnodematrix(componenttypes::Vector{Symbol}, nodeindices::Matrix{Int},
componentvalues::Vector, valuecomponenttypes::Vector, Nmodes, Nnodes,
component::Symbol, invert::Bool)
Returns either the capacitance or conductance matrix depending on the values of component
and invert
. :C
and false
for capacitance and :R
and true
for conductance. The dimensions of the output are (Nnodes-1)
times Nmodes
by (Nnodes-1)
times Nmodes
. Note that nodeindices
is "one indexed" so 1 is the ground node.
JosephsonCircuits.calcnodes
— Methodcalcnodes(nodeindex::Int, mutualinductorindex::Int,
componenttypes::Vector{Symbol}, nodeindexarray::Matrix,
componentnamedict::Dict, mutualinductorbranchnames::Vector{String})
Calculate the two nodes (or mutual inductor indices) given the index in the typvector and the component type. For component types where order matters, such as mutual inductors, the nodes are not sorted. For other component types where order does not matter, the nodes are sorted.
Examples
@variables R Cc L1 L2 Cj1 Cj2 I1 V1
@variables Ipump Rleft L1 K1 K2 L2 C2 C3
circuit = Vector{Tuple{String,String,String,Num}}(undef,0)
push!(circuit,("P1","1","0",1))
push!(circuit,("I1","1","0",Ipump))
push!(circuit,("R1","1","0",Rleft))
push!(circuit,("L1","1","0",L1))
push!(circuit,("K1","L1","L2",K1))
push!(circuit,("K2","L1","L2",K2))
push!(circuit,("L2","2","0",L2))
push!(circuit,("C2","2","0",C2))
push!(circuit,("C3","2","0",C3))
psc = JosephsonCircuits.parsesortcircuit(circuit)
println(JosephsonCircuits.calcnodes(1,1,psc.componenttypes,psc.nodeindices, psc.componentnamedict,psc.mutualinductorbranchnames))
println(JosephsonCircuits.calcnodes(5,1,psc.componenttypes,psc.nodeindices, psc.componentnamedict,psc.mutualinductorbranchnames))
# output
(1, 2)
(4, 7)
JosephsonCircuits.calcnodesorting
— Methodcalcnodesorting(uniquenodevector::Vector{String};sorting=:number)
Sort the unique node names in uniquenodevector
according to the specified sorting scheme, always placing the ground node at the beginning. Return the indices which sort uniquenodevector
.
Keywords
sorting = :name
: Sort the vector of strings. This always works but leads to results like "101" comes before "11".sorting = :number
: Convert the node strings to integer and sort by these (this errors if the nodes names cannot be converted to integers).sorting = :none
: Don't perform any sorting except to place the ground node first. In other words, order the nodes in the order they are found incircuit
.
Examples
julia> JosephsonCircuits.calcnodesorting(["30","11","0","2"];sorting=:name)
4-element Vector{Int64}:
3
2
4
1
julia> JosephsonCircuits.calcnodesorting(["30","11","0","2"];sorting=:number)
4-element Vector{Int64}:
3
4
2
1
julia> JosephsonCircuits.calcnodesorting(["30","11","0","2"];sorting=:none)
4-element Vector{Int64}:
3
1
2
4
JosephsonCircuits.calcnoiseportimpedanceindices
— Methodcalcnoiseportimpedanceindices(componenttypes::Vector{Symbol},
nodeindexarray::Matrix{Int}, mutualinductorbranchnames::Vector,
componentvalues::Vector)
Find the resistors (not located at a port) or lossy capacitors or lossy inductors and return their indices.
Examples
JosephsonCircuits.calcnoiseportimpedanceindices(
[:R,:C,:Lj,:C],
[2 2 3 3; 1 3 1 1],
[],
[50,5e-15,1e-12,30e-15])
# output
1-element Vector{Int64}:
1
JosephsonCircuits.calcnoiseportimpedanceindices(
[:P,:R,:C,:Lj,:C],
[2 2 2 3 3; 1 1 3 1 1],
[],
[1,50,5e-15,1e-12,30e-15])
# output
Int64[]
JosephsonCircuits.calcnoiseportimpedanceindices(
[:R,:C,:Lj,:C],
[2 2 3 3; 1 3 1 1],
[],
[50,5e-15,1e-12,(30+1im)*1e-15])
# output
2-element Vector{Int64}:
1
4
JosephsonCircuits.calcnoiseportimpedanceindices(
[:R,:C,:L,:C],
[2 2 3 3; 1 3 1 1],
[],
[50,5e-15,(1+1im)*1e-12,30e-15])
# output
2-element Vector{Int64}:
1
3
JosephsonCircuits.calcphiindices
— Methodcalcphiindices(frequencies::Frequencies{N},
conjsymdict::Dict{CartesianIndex{N},CartesianIndex{N}})
Return the indices which map the elements of the frequency domain vector to the corresponding elements of the frequency domain array. Also return the indices conjsourceindices
whose data should be copied from the vector to conjtargetindices
in the array then complex conjugated.
Arguments
Nt
: tuple with dimensions of signal in time domaindropdict
: dictionary of elements of frequency domain signal to drop where the key is the Cartesian index and the value is the value.
Returns
indexmap
: the indices which map the elements of the frequency domain vector elements to the corresponding elements of the frequency domain arrayconjsourceindices
: data should be copied from hereconjtargetindices
: data should be copied to here and conjugated
Examples
freq = JosephsonCircuits.Frequencies{2}((4, 3), (5, 7), (8, 7), CartesianIndex{2}[CartesianIndex(2, 1), CartesianIndex(4, 1), CartesianIndex(1, 2), CartesianIndex(3, 2), CartesianIndex(2, 3), CartesianIndex(1, 4), CartesianIndex(2, 6), CartesianIndex(3, 7)], [(1, 0), (3, 0), (0, 1), (2, 1), (1, 2), (0, 3), (1, -2), (2, -1)])
conjsymdict = Dict{CartesianIndex{2}, CartesianIndex{2}}(CartesianIndex(5, 4) => CartesianIndex(5, 5), CartesianIndex(1, 3) => CartesianIndex(1, 6), CartesianIndex(5, 2) => CartesianIndex(5, 7), CartesianIndex(1, 4) => CartesianIndex(1, 5), CartesianIndex(1, 2) => CartesianIndex(1, 7), CartesianIndex(5, 3) => CartesianIndex(5, 6))
JosephsonCircuits.calcphiindices(freq, conjsymdict)
# output
([2, 4, 6, 8, 12, 16, 27, 33], [6, 16], [31, 21])
freq = JosephsonCircuits.calcfreqsrdft((4,3));
truncfreq = JosephsonCircuits.truncfreqs(freq;dc=false,odd=true,even=false,maxintermodorder=3)
noconjtruncfreq = JosephsonCircuits.removeconjfreqs(truncfreq)
conjsymdict = JosephsonCircuits.conjsym(noconjtruncfreq)
JosephsonCircuits.calcphiindices(noconjtruncfreq,conjsymdict)
# output
([2, 4, 6, 8, 12, 16, 27, 33], [6, 16], [31, 21])
JosephsonCircuits.calcportimpedanceindices
— Methodcalcportimpedanceindices(componenttypes::Vector{Symbol},
nodeindexarray::Matrix{Int},mutualinductorbranchnames::Vector,
componentvalues::Vector)
Find the resistors located at a port and return their indices.
Examples
JosephsonCircuits.calcportimpedanceindices(
[:P,:R,:C,:Lj,:C],
[2 2 2 3 3; 1 1 3 1 1],
[],
[1,50,5e-15,1e-12,30e-15])
# output
1-element Vector{Int64}:
2
JosephsonCircuits.calcportimpedanceindices(
[:R,:C,:Lj,:C],
[2 2 3 3; 1 3 1 1],
[],
[50,5e-15,1e-12,30e-15])
# output
Int64[]
JosephsonCircuits.calcportimpedanceindices(
[:P,:R,:C,:Lj,:C,:P,:R],
[2 3 2 3 3 3 2; 1 1 3 1 1 1 1],
[],
[1,50,5e-15,1e-12,30e-15,2,50.0])
# output
2-element Vector{Int64}:
7
2
JosephsonCircuits.calcportimpedanceindices(
[:P,:R,:C,:Lj,:C,:P,:R],
[2 2 2 3 3 3 3; 1 1 3 1 1 1 1],
[],
[1,50,5e-15,1e-12,30e-15,2,50.0])
# output
2-element Vector{Int64}:
2
7
JosephsonCircuits.calcportimpedanceindices(
[:P,:R,:C,:Lj,:C,:P,:R],
[2 2 2 3 3 3 3; 1 1 3 1 1 1 1],
[],
[2,50,5e-15,1e-12,30e-15,1,50.0])
# output
2-element Vector{Int64}:
7
2
JosephsonCircuits.calcportindicesnumbers
— Methodcalcportindicesnumbers(componenttypes::Vector{Symbol},
nodeindexarray::Matrix{Int},mutualinductorbranchnames::Vector,
componentvalues::Vector)
Return vectors containing the indices of the ports and their numbers.
Examples
JosephsonCircuits.calcportindicesnumbers(
[:P,:R,:C,:Lj,:C],
[2 2 2 3 3; 1 1 3 1 1],
[],
[1,50,5e-15,1e-12,30e-15])
# output
([1], [1])
JosephsonCircuits.calcportindicesnumbers(
[:P,:R,:C,:Lj,:P],
[2 2 2 3 3; 1 1 3 1 1],
[],
[1,50,5e-15,1e-12,2])
# output
([1, 5], [1, 2])
JosephsonCircuits.calcportindicesnumbers(
[:P,:R,:C,:Lj,:P],
[2 2 2 3 3; 1 1 3 1 1],
[],
[2,50,5e-15,1e-12,1])
# output
([5, 1], [1, 2])
JosephsonCircuits.calcportindicesnumbers(
[:R,:C,:Lj,:C],
[2 2 3 3; 1 3 1 1],
[],
[50,5e-15,1e-12,30e-15])
# output
(Int64[], Int64[])
JosephsonCircuits.calcqe!
— Methodcalcqe!(qe, S, Snoise)
Calculate the quantum efficiency matrix for a scattering matrix in the field ladder operator basis. Overwrites qe with output.
Examples
julia> qe=Float64[1 2;3 4];JosephsonCircuits.calcqe!(qe,[1 2;3 4],[1 2 3;4 5 6]);qe
2×2 Matrix{Float64}:
0.0526316 0.210526
0.0882353 0.156863
JosephsonCircuits.calcqe!
— Methodcalcqe!(qe, S)
Calculate the quantum efficiency matrix for a scattering matrix in the field ladder operator basis. Overwrites qe with output.
JosephsonCircuits.calcqe
— Methodcalcqe(S)
Calculate the quantum efficiency matrix for a scattering matrix in the field ladder operator basis.
Examples
julia> JosephsonCircuits.calcqe([3/5 4/5;4/5 3/5])
2×2 Matrix{Float64}:
0.36 0.64
0.64 0.36
julia> JosephsonCircuits.calcqe(Complex{Float64}[3/5 4/5;4/5 3/5])
2×2 Matrix{Float64}:
0.36 0.64
0.64 0.36
julia> @variables a b c d;JosephsonCircuits.calcqe([a b; c d])
2×2 Matrix{Num}:
abs2(a) / (abs2(a) + abs2(b)) abs2(b) / (abs2(a) + abs2(b))
abs2(c) / (abs2(c) + abs2(d)) abs2(d) / (abs2(c) + abs2(d))
JosephsonCircuits.calcqe
— Methodcalcqe(S, Snoise)
Calculate the quantum efficiency matrix for a scattering matrix in the field ladder operator basis.
Examples
julia> JosephsonCircuits.calcqe([3/5 4/5;4/5 3/5],[0.0 0.0;0.0 0.0])
2×2 Matrix{Float64}:
0.36 0.64
0.64 0.36
julia> JosephsonCircuits.calcqe(Complex{Float64}[3/5 4/5;4/5 3/5],Complex{Float64}[0.0 0.0;0.0 0.0])
2×2 Matrix{Float64}:
0.36 0.64
0.64 0.36
julia> @variables a b c d an bn cn dn;JosephsonCircuits.calcqe([a b; c d],[an bn; cn dn])
2×2 Matrix{Num}:
abs2(a) / (abs2(an) + abs2(a) + abs2(b) + abs2(bn)) … abs2(b) / (abs2(an) + abs2(a) + abs2(b) + abs2(bn))
abs2(c) / (abs2(c) + abs2(cn) + abs2(d) + abs2(dn)) abs2(d) / (abs2(c) + abs2(cn) + abs2(d) + abs2(dn))
JosephsonCircuits.calcqeideal!
— Methodcalcqeideal!(qeideal,S)
See calcqeideal
.
JosephsonCircuits.calcqeideal
— Methodcalcqeideal(S::AbstractArray)
Calculate the ideal (best possible) quantum efficiency for each element of a scattering matrix. See also calcqeideal!
.
Examples
julia> JosephsonCircuits.calcqeideal([3/5 4/5;4/5 3/5])
2×2 Matrix{Float64}:
1.0 1.0
1.0 1.0
julia> JosephsonCircuits.calcqeideal(Complex{Float64}[3/5 4/5;4/5 3/5])
2×2 Matrix{Float64}:
1.0 1.0
1.0 1.0
JosephsonCircuits.calcscatteringmatrix!
— Methodcalcscatteringmatrix!(S, inputwave, outputwave)
The scattering matrix is defined as outputwave = S * inputwave
.
Examples
julia> inputwave=[1.0 0.0;0.0 1.0];outputwave=[im/sqrt(2) 1/sqrt(2);1/sqrt(2) im/sqrt(2)];S = zeros(Complex{Float64},2,2);JosephsonCircuits.calcscatteringmatrix!(S,inputwave,outputwave);S
2×2 Matrix{ComplexF64}:
0.0+0.707107im 0.707107+0.0im
0.707107+0.0im 0.0+0.707107im
julia> inputwave = rand(Complex{Float64},2,2);outputwave = rand(Complex{Float64},2,2);S=zeros(Complex{Float64},2,2);JosephsonCircuits.calcscatteringmatrix!(S,inputwave,outputwave);isapprox(S*inputwave,outputwave)
true
JosephsonCircuits.calcscatteringmatrix!
— Methodcalcscatteringmatrix!(S, inputwave::Diagonal, outputwave)
The scattering matrix is defined as outputwave = S * inputwave
.
Examples
julia> inputwave=JosephsonCircuits.LinearAlgebra.Diagonal([1.0,1.0]);outputwave=[im/sqrt(2) 1/sqrt(2);1/sqrt(2) im/sqrt(2)];S = zeros(Complex{Float64},2,2);JosephsonCircuits.calcscatteringmatrix!(S,inputwave,outputwave);S
2×2 Matrix{ComplexF64}:
0.0+0.707107im 0.707107+0.0im
0.707107+0.0im 0.0+0.707107im
JosephsonCircuits.calcscatteringmatrix!
— Methodcalcscatteringmatrix!(S, inputwave::Vector, outputwave::Vector)
The scattering matrix is defined as outputwave = S * inputwave
.
Examples
julia> inputwave=[1.0,0.0];outputwave=[im/sqrt(2), 1/sqrt(2)];S = zeros(Complex{Float64},2,2);JosephsonCircuits.calcscatteringmatrix!(S,inputwave,outputwave);S
2×2 Matrix{ComplexF64}:
0.0+0.707107im 0.0+0.0im
0.707107+0.0im 0.0+0.0im
JosephsonCircuits.calcsources
— Methodcalcsources(modes, sources, portindices, portnumbers, nodeindices,
edge2indexdict, Lmean, Nnodes, Nbranches, Nmodes)
Calculate the source terms in the branch basis. See also addsources!
.
Examples
modes = [(0,), (1,)]
sources = [(mode = (0,), port = 1, current = 0.0005), (mode = (1,), port = 1, current = 1.0e-10)]
portindices = [1]
portnumbers = [1]
nodeindices = [2 2 2 2 0 2 3 4 3 3; 1 1 1 1 0 3 4 1 1 1]
edge2indexdict = Dict((1, 2) => 1, (3, 1) => 2, (1, 3) => 2, (4, 1) => 3, (2, 1) => 1, (1, 4) => 3, (3, 4) => 4, (4, 3) => 4)
Lmean = 1.005e-9 + 0.0im
Nnodes = 4
Nbranches = 4
Nmodes = 2
JosephsonCircuits.calcsources(modes, sources, portindices, portnumbers,
nodeindices, edge2indexdict, Lmean, Nnodes, Nbranches, Nmodes)
# output
8-element Vector{ComplexF64}:
1526.863796602709 + 0.0im
0.0003053727593205418 + 0.0im
0.0 + 0.0im
0.0 + 0.0im
0.0 + 0.0im
0.0 + 0.0im
0.0 + 0.0im
0.0 + 0.0im
JosephsonCircuits.calcspicesortperms
— Methodcalcspicesortperms(variabledict::Dict{String,Vector{String}})
Calculate the sortperms which will sort the variable and node names.
Examples
julia> JosephsonCircuits.calcspicesortperms(Dict("V" => ["v(1)", "v(2)", "v(3)"], "Hz" => ["frequency"]))
Dict{String, Vector{Int64}} with 2 entries:
"V" => [1, 2, 3]
"Hz" => [1]
JosephsonCircuits.calcvaluetype
— Methodcalcvaluetype(componenttypes::Vector{Symbol},componentvalues::Vector,
components::Vector{Symbol};checkinverse::Bool=true)
Returns a zero length vector with the (computer science) type which will hold a set of circuit components of the (electrical engineering) types given in components
. This function is not type stable by design, but exists to make the later function calls type stable.
Arguments
componenttypes::Vector{Symbol}
: the component (electrical engineering) types.componentvalues::Vector
: the component values.components::Vector{Symbol}
: find a (computer science) type which will hold the component (electrical engineering) types in this vector.
Keywords
checkinverse = true
: also check the inverse of each element. This is useful if the type would be integer but we later want to take the inverse and want an array with a type that supports this operation.
Examples
julia> JosephsonCircuits.calcvaluetype([:R,:C,:R],[1,2,3],[:R])
Float64[]
julia> JosephsonCircuits.calcvaluetype([:R,:C,:R],[1,2,3+0.0im],[:R])
ComplexF64[]
julia> @variables R1 C1 R2;JosephsonCircuits.calcvaluetype([:R,:C,:R],[R1,C1,R2],[:R])
Num[]
JosephsonCircuits.calcw!
— Methodcalcw!(ws, i, wp, w)
Generate the signal and idler frequencies using the formula ws + 2iwp. Overwrites w with output.
JosephsonCircuits.calcw
— Methodcalcw(ws::Number, i::Integer, wp::Number)
Generate the signal and idler frequencies using the formula ws + 2iwp.
Should I switch this to ws+i*wp so it can handle three wave mixing then always double i for four wave mixing?
Examples
julia> JosephsonCircuits.calcw(2*pi*4.0e9,-1,2*pi*5.0e9)/(2*pi*1.0e9)
-5.999999999999999
julia> JosephsonCircuits.calcw(2*pi*4.0e9,[-1,0,1],2*pi*5.0e9)/(2*pi*1.0e9)
3-element Vector{Float64}:
-5.999999999999999
4.0
14.0
julia> JosephsonCircuits.calcw([2*pi*4.0e9,2*pi*4.1e9],[-1,0,1],2*pi*5.0e9)/(2*pi*1.0e9)
2×3 Matrix{Float64}:
-6.0 4.0 14.0
-5.9 4.1 14.1
JosephsonCircuits.cascadeS!
— MethodcascadeS!(S, Sa, Sb)
See cascadeS
for description.
JosephsonCircuits.cascadeS
— MethodcascadeS(Sa,Sb)
Cascade the scattering parameter matrix Sa
with the scattering matrix Sb
and return the combined scattering matrix.
Examples
julia> Sa = [0.0 0.5;0.5 0.0];Sb = [0.0 0.1;0.1 0.0];JosephsonCircuits.cascadeS(Sa,Sb)
2×2 Matrix{Float64}:
0.0 0.05
0.05 0.0
julia> Sa=rand(Complex{Float64},2,2);Sb=rand(Complex{Float64},2,2);isapprox(JosephsonCircuits.cascadeS(Sa,Sb),JosephsonCircuits.AtoS(JosephsonCircuits.StoA(Sa)*JosephsonCircuits.StoA(Sb)))
true
julia> Sa=[rand(Complex{Float64},2,2) for i in 1:10];Sb=[rand(Complex{Float64},2,2) for i in 1:10];isapprox(JosephsonCircuits.cascadeS.(Sa,Sb),JosephsonCircuits.AtoS.(JosephsonCircuits.StoA.(Sa).*JosephsonCircuits.StoA.(Sb)))
true
References
D. J. R. Stock and L. J. Kaplan, "A Comment on the Scattering Matrix of Cascaded 2n-Ports (Correspondence)," in IRE Transactions on Microwave Theory and Techniques, vol. 9, no. 5, pp. 454-454, September 1961, doi: 10.1109/TMTT.1961.1125369 .
JosephsonCircuits.checkcomponenttypes
— Methodcheckcomponenttypes(allowedcomponents::Vector{String})
Check that each element in allowedcomponents
is found at the correct place. This will detect the case where a two letter component appears in allowedcomponents
after a one letter component with the same starting letter. The function parsecomponenttype() will match on the first value and this function will throw an error.
Examples
julia> JosephsonCircuits.checkcomponenttypes(["Lj","L","C","K","I","R","P"])
true
JosephsonCircuits.checkissymbolic
— Methodcheckissymbolic(a)
Check if a
is a symbolic variable. Define a function to do this because a different function call is required for @syms
vs @variables
.
Examples
julia> @variables w;JosephsonCircuits.checkissymbolic(w)
true
julia> JosephsonCircuits.checkissymbolic(1.0)
false
JosephsonCircuits.checkissymbolic
— Methodcheckissymbolic(a::Num)
Check if a
is a symbolic variable.
Examples
julia> @variables w;JosephsonCircuits.checkissymbolic(w)
true
JosephsonCircuits.comparearray
— Methodcomparearray(x::AbstractArray{T},y::AbstractArray{T}) where T
Compare two arrays for testing purposes.
Examples
julia> JosephsonCircuits.comparearray([1,2],[1,2,3])
false
julia> JosephsonCircuits.comparearray([1,2],[1,2,])
true
JosephsonCircuits.comparestruct
— Methodcomparestruct(x,y)
Compare two structures for testing purposes.
Examples
julia> JosephsonCircuits.comparestruct(JosephsonCircuits.warmupnumericmatrices(),JosephsonCircuits.warmupnumericmatrices())
true
julia> JosephsonCircuits.comparestruct(JosephsonCircuits.warmup(),JosephsonCircuits.warmup())
true
julia> JosephsonCircuits.comparestruct(nothing,nothing)
true
julia> JosephsonCircuits.compare(nothing,nothing)
true
julia> cg = JosephsonCircuits.CircuitGraph(Dict((1, 2) => 1, (3, 1) => 2, (1, 3) => 2, (2, 1) => 1), JosephsonCircuits.SparseArrays.sparse([1, 2], [1, 2], [1, 1], 2, 2), [(1, 2), (1, 3)], Tuple{Int64, Int64}[], [(1, 2), (1, 3)], Vector{Int64}[], Int64[], JosephsonCircuits.Graphs.SimpleGraphs.SimpleGraph{Int64}(2, [[2, 3], [1], [1]]), 2);JosephsonCircuits.compare(cg,cg)
true
JosephsonCircuits.componentdictionaries
— Methodcomponentdictionaries(componenttypes::Vector{Symbol},
nodeindexarray::Matrix{Int}, componentnamedict::Dict,
mutualinductorbranchnames::Vector)
Examples
@variables Ipump Rleft L1 K1 L2 C2 C3
circuit = Vector{Tuple{String,String,String,Num}}(undef,0)
push!(circuit,("P1","1","0",1))
push!(circuit,("I1","1","0",Ipump))
push!(circuit,("R1","1","0",Rleft))
push!(circuit,("L1","1","0",L1))
push!(circuit,("K1","L1","L2",K1))
push!(circuit,("L2","2","0",L2))
push!(circuit,("C2","2","0",C2))
push!(circuit,("C3","2","0",C3))
psc = parsesortcircuit(circuit)
countdict, indexdict = JosephsonCircuits.componentdictionaries(psc.componenttypes,psc.nodeindices,psc.componentnamedict,psc.mutualinductorbranchnames)
println(countdict)
println(indexdict)
# output
Dict((:L, 1, 3) => 1, (:K, 4, 6) => 1, (:R, 1, 2) => 1, (:I, 1, 2) => 1, (:P, 1, 2) => 1, (:C, 1, 3) => 2, (:L, 1, 2) => 1)
Dict((:C, 1, 3, 1) => 7, (:I, 1, 2, 1) => 2, (:R, 1, 2, 1) => 3, (:L, 1, 3, 1) => 6, (:C, 1, 3, 2) => 8, (:L, 1, 2, 1) => 4, (:P, 1, 2, 1) => 1, (:K, 4, 6, 1) => 5)
@variables Ipump Rleft L1 K1 K2 L2 C2 C3
circuit = Vector{Tuple{String,String,String,Num}}(undef,0)
push!(circuit,("P1","1","0",1))
push!(circuit,("I1","1","0",Ipump))
push!(circuit,("R1","1","0",Rleft))
push!(circuit,("L1","1","0",L1))
push!(circuit,("K1","L1","L2",K1))
push!(circuit,("K2","L1","L2",K2))
push!(circuit,("L2","2","0",L2))
push!(circuit,("C2","2","0",C2))
push!(circuit,("C3","2","0",C3))
psc = parsesortcircuit(circuit)
countdict, indexdict = JosephsonCircuits.componentdictionaries(psc.componenttypes,psc.nodeindices,psc.componentnamedict,psc.mutualinductorbranchnames)
println(countdict)
println(indexdict)
# output
Dict((:L, 1, 3) => 1, (:K, 4, 7) => 2, (:R, 1, 2) => 1, (:I, 1, 2) => 1, (:P, 1, 2) => 1, (:C, 1, 3) => 2, (:L, 1, 2) => 1)
Dict((:C, 1, 3, 1) => 8, (:I, 1, 2, 1) => 2, (:R, 1, 2, 1) => 3, (:K, 4, 7, 1) => 5, (:K, 4, 7, 2) => 6, (:L, 1, 2, 1) => 4, (:L, 1, 3, 1) => 7, (:P, 1, 2, 1) => 1, (:C, 1, 3, 2) => 9)
JosephsonCircuits.componentvaluestonumber
— Methodcomponentvaluestonumber(componentvalues::Vector,circuitdefs::Dict)
Convert the array of component values to numbers, if defined in circuitdefs
. This function is not type stable by design because we want the output array to use a concrete type if all of the values are evaluated to numbers.
Examples
julia> JosephsonCircuits.componentvaluestonumber([:Lj1,:Lj2],Dict(:Lj1=>1e-12,:Lj2=>2e-12))
2-element Vector{Float64}:
1.0e-12
2.0e-12
julia> @variables Lj1 Lj2;JosephsonCircuits.componentvaluestonumber([Lj1,Lj1+Lj2],Dict(Lj1=>1e-12,Lj2=>2e-12))
2-element Vector{Float64}:
1.0e-12
3.0e-12
# define a frequency dependent impedance function
Zfun(w,R) = ifelse(w>10,R,100*R);
# create symbolic variables including a two argument function
@variables w R
@register_symbolic Zfun(w,R)
# substitute in numerical values and functions for everything but w
out=JosephsonCircuits.componentvaluestonumber([R,Zfun(w,R)],Dict(R=>50));
println(out)
# evaluate with w = 2
println(JosephsonCircuits.Symbolics.substitute.(out,(Dict(w=>2),)))
# evaluate with w = 11
println(JosephsonCircuits.Symbolics.substitute.(out,(Dict(w=>11),)))
# output
Any[50, Zfun(w, 50)]
[50, 5000]
[50, 50]
JosephsonCircuits.conjnegfreq!
— Methodconjnegfreq!(A, wmodes)
Take the complex conjugate of any element of A
which would be negative when multipled from the right by a diagonal matrix consisting of wmodes
replicated along the diagonal. Overwrite A
with the output.
Each axis of A
should be an integer multiple of the length of wmodes
.
Examples
julia> A = JosephsonCircuits.SparseArrays.sparse([1,2,1,2], [1,1,2,2], [1+1im,1+1im,1+1im,1+1im],2,2);JosephsonCircuits.conjnegfreq!(A,[-1,1]);A
2×2 SparseArrays.SparseMatrixCSC{Complex{Int64}, Int64} with 4 stored entries:
1-1im 1+1im
1-1im 1+1im
JosephsonCircuits.conjnegfreq
— Methodconjnegfreq(A, wmodes)
Take the complex conjugate of any element of A
which would be negative when multipled from the right by a diagonal matrix consisting of wmodes
replicated along the diagonal.
Each axis of A
should be an integer multiple of the length of wmodes
.
Examples
julia> A = JosephsonCircuits.SparseArrays.sparse([1,2,1,2], [1,1,2,2], [1+1im,1+1im,1+1im,1+1im],2,2);JosephsonCircuits.conjnegfreq(A,[-1,1])
2×2 SparseArrays.SparseMatrixCSC{Complex{Int64}, Int64} with 4 stored entries:
1-1im 1+1im
1-1im 1+1im
julia> A = JosephsonCircuits.SparseArrays.sparse([1,2,1,2], [1,1,2,2], [1im,1im,1im,1im],2,2);all(A*JosephsonCircuits.LinearAlgebra.Diagonal([-1,1]) .== JosephsonCircuits.conjnegfreq(A,[-1,1]))
true
JosephsonCircuits.conjsym
— Methodconjsym(Nw::NTuple{N, Int}, Nt::NTuple{N, Int})
Calculate the conjugate symmetries in the multi-dimensional frequency domain data.
Examples
julia> JosephsonCircuits.conjsym(JosephsonCircuits.calcfreqsrdft((2,)))
Dict{CartesianIndex{1}, CartesianIndex{1}}()
julia> JosephsonCircuits.conjsym(JosephsonCircuits.calcfreqsdft((2,)))
Dict{CartesianIndex{1}, CartesianIndex{1}} with 2 entries:
CartesianIndex(2,) => CartesianIndex(5,)
CartesianIndex(3,) => CartesianIndex(4,)
julia> JosephsonCircuits.conjsym(JosephsonCircuits.calcfreqsrdft((2,1)))
Dict{CartesianIndex{2}, CartesianIndex{2}} with 2 entries:
CartesianIndex(1, 2) => CartesianIndex(1, 3)
CartesianIndex(3, 2) => CartesianIndex(3, 3)
julia> JosephsonCircuits.conjsym(JosephsonCircuits.calcfreqsdft((2,1)))
Dict{CartesianIndex{2}, CartesianIndex{2}} with 7 entries:
CartesianIndex(2, 3) => CartesianIndex(5, 2)
CartesianIndex(2, 1) => CartesianIndex(5, 1)
CartesianIndex(3, 3) => CartesianIndex(4, 2)
CartesianIndex(3, 1) => CartesianIndex(4, 1)
CartesianIndex(2, 2) => CartesianIndex(5, 3)
CartesianIndex(1, 2) => CartesianIndex(1, 3)
CartesianIndex(3, 2) => CartesianIndex(4, 3)
julia> JosephsonCircuits.conjsym(JosephsonCircuits.calcfreqsrdft((2,1,1)))
Dict{CartesianIndex{3}, CartesianIndex{3}} with 8 entries:
CartesianIndex(1, 2, 1) => CartesianIndex(1, 3, 1)
CartesianIndex(1, 2, 3) => CartesianIndex(1, 3, 2)
CartesianIndex(1, 2, 2) => CartesianIndex(1, 3, 3)
CartesianIndex(3, 2, 1) => CartesianIndex(3, 3, 1)
CartesianIndex(1, 1, 2) => CartesianIndex(1, 1, 3)
CartesianIndex(3, 2, 3) => CartesianIndex(3, 3, 2)
CartesianIndex(3, 2, 2) => CartesianIndex(3, 3, 3)
CartesianIndex(3, 1, 2) => CartesianIndex(3, 1, 3)
JosephsonCircuits.connectS!
— MethodconnectS!(Sout,Sa,Sb,k,l)
See connectS
for description.
JosephsonCircuits.connectS!
— MethodconnectS!(Sout, Sa, k::Int, l::Int; nbatches::Int = Base.Threads.nthreads())
See connectS
for description.
JosephsonCircuits.connectS!
— MethodconnectS!(g::Graphs.SimpleGraphs.SimpleDiGraph{Int},
fconnectionlist::AbstractVector{<:AbstractVector{Tuple{T,T,Int,Int}}},
fweightlist::AbstractVector{<:AbstractVector{Int}},
ports::AbstractVector{<:AbstractVector{Tuple{T,Int}}},
networkdata::AbstractVector{N};
nbatches::Int = Base.Threads.nthreads()) where {T,N}
Return the non-empty elements of the updated networkdata
and ports
after applying all of the connections in the connection forward adjacency list fconnectionlist
to the graph g
, the forward adjacency weight list fweightlist
, the vector of ports ports
, and the vector of scattering parameter matrices networkdata
.
Examples
networks = [("S1",[0.0 1.0;1.0 0.0]),("S2",[0.5 0.5;0.5 0.5])];
connections = [[("S1",1),("S2",2)]];
init = JosephsonCircuits.connectS_initialize(networks, connections);
JosephsonCircuits.connectS!(init...)
# output
(S = [[0.5 0.5; 0.5 0.5]], ports = [[("S1", 2), ("S2", 1)]])
JosephsonCircuits.connectS
— MethodconnectS(networks, connections; small_splitters::Bool = true,
nbatches::Int = Base.Threads.nthreads())
Return the network and ports resulting from connecting the networks in networks
according to the connections in connections
. networks
is a vector of tuples of the network name and scattering parameter matrix such as [("network1name",rand(Complex{Float64},2,2), ("network2name",rand(Complex{Float64},2,2)]. connections
is a vector of vectors of tuples of networks names and ports such as [[("network1name",1), ("network2name",2)]] where network1 and network2 are the two networks being connected and 1 and 2 are integers describing the ports to connect.
This function supports connections between more than two ports by automatically adding splitters.
Examples
networks = [("S1",[0.0 1.0;1.0 0.0]),("S2",[0.5 0.5;0.5 0.5])];
connections = [[("S1",1),("S2",2)]];
JosephsonCircuits.connectS(networks,connections)
# output
(S = [[0.5 0.5; 0.5 0.5]], ports = [[("S1", 2), ("S2", 1)]])
networks = [("S1",[0.0 1.0;1.0 0.0]),("S2",[0.5 0.5;0.5 0.5],[("S3",5),("S3",6)])];
connections = [("S1","S3",1,6)];
JosephsonCircuits.connectS(networks,connections)
# output
(S = [[0.5 0.5; 0.5 0.5]], ports = [[("S1", 2), ("S3", 5)]])
JosephsonCircuits.connectS
— MethodconnectS(Sa::AbstractArray,Sb::AbstractArray,k::Int,l::Int;
nbatches::Int = Base.Threads.nthreads())
Connect port k
on an m
port network, represented by the scattering parameter matrix Sa
, to port l
on an n
port network, represented by the scattering parameter matrix Sb
, resulting in a single (m+n-2)
port network, as illustrated below:
Input network:
m | | k+1 | 2
| | |
| ... | ... |
|________| _________|________
| | | | 1
| Sa | | Sb |
| m x m | | n x n |
____|________|__________________|________|
1 | ... k l | ... |
| | |
| | |
2 | l+1 | | n
Output network:
m-1 | | k | m+1
| | |
| ... | ... |
|________|________|________
| | m
| S |
| m+n-2 x m+n-2 |
____|_________________|
1 | ... | ... |
| | |
| | |
2 | | | m+n-2
m-1+l
Arguments
Sa::Array
: Array of scattering parameters representing the first network with ports along first two dimensions, followed by an arbitrary number of other dimensions (eg. frequency).Sb::Array
: Array of scattering parameters representing the second network with ports along first two dimensions, followed by an arbitrary number of other dimensions (eg. frequency).k::Int
: Port on first network, with one based indexing.l::Int
: Port on second network, with one based indexing.
References
V. A. Monaco and P. Tiberio, "Computer-Aided Analysis of Microwave Circuits," in IEEE Transactions on Microwave Theory and Techniques, vol. 22, no. 3, pp. 249-263, Mar. 1974, doi: 10.1109/TMTT.1974.1128208.
JosephsonCircuits.connectS
— MethodconnectS(Sa::AbstractArray, k::Int, l::Int;
nbatches::Int = Base.Threads.nthreads())
Connect ports k
and l
on the same m
port microwave network represented by the scattering parameter matrix Sa
, resulting in an (m-2)
port network, as illustrated below:
Input network:
m | | l+1
| ... | l
|_________|__________
| | |
| Sa | ... |
| m x m | |
____|_________|_____ k+1 |
1 | ... | |
| | k |
2 | |__________|
Output network:
m-2 | | l-1
| |
| ... |
|_________|
| |
| S | ...
|m-2 x m-2|
____|_________|_________
1 | ... k
|
|
2 |
Arguments
Sa::Array
: Array of scattering parameters representing the network with ports along first two dimensions, followed by an arbitrary number of other dimensions (eg. frequency).k::Int
: First port to connect, with one based indexing.l::Int
: Second port to connect, with one based indexing.
References
V. A. Monaco and P. Tiberio, "Computer-Aided Analysis of Microwave Circuits," in IEEE Transactions on Microwave Theory and Techniques, vol. 22, no. 3, pp. 249-263, Mar. 1974, doi: 10.1109/TMTT.1974.1128208.
JosephsonCircuits.connectS_initialize
— MethodconnectS_initialize(networks::AbstractVector, connections::AbstractVector;
small_splitters::Bool = true)
Return a directed graph of connections between the networks.
Examples
networks = [("S1",[0.0 1.0;1.0 0.0]),("S2",[0.5 0.5;0.5 0.5])];
connections = [[("S1",1),("S2",2)]];
JosephsonCircuits.connectS_initialize(networks,connections)
# output
(Graphs.SimpleGraphs.SimpleDiGraph{Int64}(2, [[2], Int64[]], [Int64[], [1]]), [[("S1", "S2", 1, 2)], Tuple{String, String, Int64, Int64}[]], [[1], Int64[]], [[("S1", 1), ("S1", 2)], [("S2", 1), ("S2", 2)]], [[0.0 1.0; 1.0 0.0], [0.5 0.5; 0.5 0.5]])
JosephsonCircuits.connectS_initialize
— MethodconnectS_initialize(networks::AbstractVector{Tuple{T,N,Vector{Tuple{T, Int}}}},
connections::AbstractVector{Tuple{T,T,Int,Int}}) where {T,N}
Return a directed graph of connections between the networks.
Examples
networks = [("S1", [0.0 1.0; 1.0 0.0], [("S1", 1), ("S1", 2)]), ("S2", [0.5 0.5; 0.5 0.5], [("S2", 1), ("S2", 2)])];
connections = [("S1","S2",1,2)];
JosephsonCircuits.connectS_initialize(networks,connections)
# output
(Graphs.SimpleGraphs.SimpleDiGraph{Int64}(2, [[2], Int64[]], [Int64[], [1]]), [[("S1", "S2", 1, 2)], Tuple{String, String, Int64, Int64}[]], [[1], Int64[]], [[("S1", 1), ("S1", 2)], [("S2", 1), ("S2", 2)]], [[0.0 1.0; 1.0 0.0], [0.5 0.5; 0.5 0.5]])
JosephsonCircuits.connectS_inner!
— MethodconnectS_inner!(Sout,Sa,Sb,k::Int,l::Int,batch::AbstractArray)
See connectS
for description.
JosephsonCircuits.connectS_inner!
— MethodconnectS_inner!(Sout, Sa, k::Int, l::Int, batch::AbstractArray)
See connectS
for description.
JosephsonCircuits.connectSports
— MethodconnectSports(portsa::AbstractVector{Tuple{T,Int}},
portsb::AbstractVector{Tuple{T,Int}}, k::Int, l::Int) where T
Return a vector of tuples of (networkname, portindex) with portsa
from the first network and portsb
from the second network after ports k
and l
from the first and second networks have been connected. If the first network has n
ports and the second network has m
ports, then the combined network has (m+n-2)
ports. See connectS
for more information.
Examples
julia> JosephsonCircuits.connectSports([(:S1,1),(:S1,2),(:S1,3),(:S1,4),(:S1,5)],[(:S2,1),(:S2,2),(:S2,3),(:S2,4),(:S2,5)],3,4)
8-element Vector{Tuple{Symbol, Int64}}:
(:S1, 1)
(:S1, 2)
(:S1, 4)
(:S1, 5)
(:S2, 1)
(:S2, 2)
(:S2, 3)
(:S2, 5)
JosephsonCircuits.connectSports
— MethodconnectSports(portsa::AbstractVector{Tuple{T,Int}},k::Int,l::Int) where T
Return a vector of tuples of (networkname, portindex) from portsa
after ports k
and l
have been connected. See connectS
for more information.
Examples
julia> JosephsonCircuits.connectSports([(:S1,1),(:S1,2),(:S1,3),(:S1,4),(:S1,5)],3,4)
3-element Vector{Tuple{Symbol, Int64}}:
(:S1, 1)
(:S1, 2)
(:S1, 5)
JosephsonCircuits.diagrepeat!
— Methoddiagrepeat!(out, A, counts::Integer)
Overwrite out
with the elements of A
duplicated counts
times along the diagonal.
Examples
julia> A = [1 2;3 4];out = zeros(eltype(A),4,4);JosephsonCircuits.diagrepeat!(out,A,2);out
4×4 Matrix{Int64}:
1 0 2 0
0 1 0 2
3 0 4 0
0 3 0 4
JosephsonCircuits.diagrepeat
— Methoddiagrepeat(A::Matrix, counts::Integer)
Return a matrix with each element of A
duplicated along the diagonal counts
times.
Examples
julia> JosephsonCircuits.diagrepeat([1 2;3 4],2)
4×4 Matrix{Int64}:
1 0 2 0
0 1 0 2
3 0 4 0
0 3 0 4
julia> JosephsonCircuits.diagrepeat([1,2],2)
4-element Vector{Int64}:
1
1
2
2
JosephsonCircuits.diagrepeat
— Methoddiagrepeat(A::Diagonal, counts::Integer)
Return a diagonal matrix with each element of A
duplicated along the diagonal counts
times.
Examples
julia> JosephsonCircuits.diagrepeat(JosephsonCircuits.LinearAlgebra.Diagonal([1,2]),2)
4×4 LinearAlgebra.Diagonal{Int64, Vector{Int64}}:
1 ⋅ ⋅ ⋅
⋅ 1 ⋅ ⋅
⋅ ⋅ 2 ⋅
⋅ ⋅ ⋅ 2
JosephsonCircuits.diagrepeat
— Methoddiagrepeat(A::SparseMatrixCSC, counts::Integer)
Return a sparse matrix with each element of A
duplicated along the diagonal counts
times.
Examples
julia> JosephsonCircuits.diagrepeat(JosephsonCircuits.SparseArrays.sparse([1,1,2,2], [1,2,1,2], [1,2,3,4],2,2),2)
4×4 SparseArrays.SparseMatrixCSC{Int64, Int64} with 8 stored entries:
1 ⋅ 2 ⋅
⋅ 1 ⋅ 2
3 ⋅ 4 ⋅
⋅ 3 ⋅ 4
JosephsonCircuits.diagrepeat
— Methoddiagrepeat(A::SparseVector, counts::Integer)
Return a sparse vector with each element of A
duplicated along the diagonal counts
times.
Examples
julia> JosephsonCircuits.diagrepeat(JosephsonCircuits.SparseArrays.sparsevec([1,2],[1,2]),2)
4-element SparseArrays.SparseVector{Int64, Int64} with 4 stored entries:
[1] = 1
[2] = 1
[3] = 2
[4] = 2
JosephsonCircuits.edge2index
— Methodedge2index(graph::Graphs.SimpleDiGraph{Int})
Generate a dictionary where the tuple of nodes defining an edge of a graph is the key and the value is an index. The index gives the order the edge is found when iterating over the edges of the graph. The same index is used for both orderings of source and destination nodes on the edge. We don't care about the ordering of the indices as long as they are sequential and unique.
Examples
julia> JosephsonCircuits.edge2index(JosephsonCircuits.Graphs.path_digraph(4))
Dict{Tuple{Int64, Int64}, Int64} with 6 entries:
(3, 2) => 2
(1, 2) => 1
(2, 1) => 1
(3, 4) => 3
(4, 3) => 3
(2, 3) => 2
JosephsonCircuits.even_odd_to_maxwell
— Methodeven_odd_to_maxwell(Zeven, Zodd, neven, nodd)
Return the inductance matrix and Maxwell capacitance matrix for two coupled transmission lines with even and odd mode impedances Zeven
, Zodd
and even and odd mode indices neven
, nodd
.
Examples
L1 = [1.1 0.1;0.1 1.1]
C1 = [2.0 -0.4;-0.4 2.0]
L2, C2 = JosephsonCircuits.even_odd_to_maxwell(JosephsonCircuits.maxwell_to_even_odd(L1,C1)...)
isapprox(L1,L2) && isapprox(C1,C2)
# output
true
JosephsonCircuits.even_odd_to_mutual
— Methodeven_odd_to_mutual(Zeven, Zodd, neven, nodd)
Return the inductance matrix and mutual capacitance matrix for two coupled transmission lines with even and odd mode impedances Zeven
, Zodd
and even and odd mode indices neven
, nodd
.
Examples
L1 = [1.1 0.1;0.1 1.1]
C1 = [1.6 0.4;0.4 1.6]
L2, C2 = JosephsonCircuits.even_odd_to_mutual(JosephsonCircuits.mutual_to_even_odd(L1,C1)...)
isapprox(L1,L2) && isapprox(C1,C2)
# output
true
JosephsonCircuits.export_netlist!
— Methodexport_netlist!(io::IO, circuit, circuitdefs)
Export the netlist in circuit
to the IOBuffer or IOStream io
.
Examples
julia> io = IOBuffer();JosephsonCircuits.export_netlist!(io, [("P","1","0",1),("R","1","0",50.0)],Dict());println(String(take!(io)))
P 1 0 1
R 1 0 50.0
JosephsonCircuits.export_netlist
— Methodexport_netlist(filename, circuit, circuitdefs)
Export the netlist in circuit
to the file with name and path filename
.
JosephsonCircuits.export_netlist
— Methodexport_netlist(filename, circuit)
Export the netlist in circuit
to the file with name and path filename
.
JosephsonCircuits.exportnetlist
— Methodexportnetlist(circuit::Vector,circuitdefs::Dict,port::Int = true,
jj::Bool = true)
Examples
@variables R Cc Lj Cj I
circuit = [
("P1","1","0",1),
("R1","1","0",R),
("C1","1","2",Cc),
("Lj1","2","0",Lj),
("C2","2","0",Cj)]
circuitdefs = Dict(
Lj =>1000.0e-12,
Cc => 100.0e-15,
Cj => 1000.0e-15,
R => 50.0)
println(JosephsonCircuits.exportnetlist(circuit, circuitdefs;port = 1, jj = true).netlist)
println("")
println(JosephsonCircuits.exportnetlist(circuit, circuitdefs;port = 1, jj = false).netlist)
# output
* SPICE Simulation
R1 1 0 50.0
C1 1 2 100.0f
B1 2 0 3 jjk ics=0.32910597599999997u
C2 2 0 674.18508376f
.model jjk jj(rtype=0,cct=1,icrit=0.32910597599999997u,cap=325.81491624f,force=1,vm=9.9
* SPICE Simulation
R1 1 0 50.0
C1 1 2 100.0f
Lj1 2 0 1000.0000000000001p
C2 2 0 1000.0f
@variables R Cc L1 L2 Cj1 Cj2 I1 V1
circuit = [
("P1","1","0",1),
("R1","1","0",R),
("C1","1","2",Cc),
("L1","2","0",L1),
("L2","2","0",L2),
("C2","2","0",Cj1),
("C3","2","0",Cj2),
("I1","2","0",I1)]
circuitdefs = Dict(
L1 =>2000.0e-12,
L2 =>2000.0e-12,
Cc => 100.0e-15,
Cj1 => 500.0e-15,
Cj2 => 500.0e-15,
R => 50.0,
I1 =>0.1)
println(JosephsonCircuits.exportnetlist(circuit, circuitdefs;port = 1, jj = true).netlist)
println("")
println(JosephsonCircuits.exportnetlist(circuit, circuitdefs;port = 1, jj = false).netlist)
# output
* SPICE Simulation
R1 1 0 50.0
C1 1 2 100.0f
L1 2 0 1000.0000000000001p
C2 2 0 1000.0f
* SPICE Simulation
R1 1 0 50.0
C1 1 2 100.0f
L1 2 0 1000.0000000000001p
C2 2 0 1000.0f
@variables Rleft L1 K1 L2 C2 C3 Lj1
circuit = Vector{Tuple{String,String,String,Num}}(undef,0)
push!(circuit,("P1","1","0",1))
push!(circuit,("R1","1","0",Rleft))
push!(circuit,("L1","1","0",L1))
push!(circuit,("Lj1","2","0",Lj1))
push!(circuit,("K1","L1","L2",K1))
push!(circuit,("L2","2","0",L2))
push!(circuit,("C2","2","0",C2))
push!(circuit,("C3","2","0",C3))
circuitdefs = Dict(
Rleft => 50.0,
L1 => 1000.0e-12,
Lj1 => 1000.0e-12,
K1 => 0.1,
L2 => 1000.0e-12,
C2 => 1000.0e-15,
C3 => 1000.0e-15)
println(JosephsonCircuits.exportnetlist(circuit, circuitdefs;port = 1, jj = true).netlist)
println("")
println(JosephsonCircuits.exportnetlist(circuit, circuitdefs;port = 1, jj = false).netlist)
# output
* SPICE Simulation
R1 1 0 50.0
L1 1 0 1000.0000000000001p
B1 2 0 3 jjk ics=0.32910597599999997u
C2 2 0 1674.18508376f
K1 L1 L2 0.1
L2 2 0 1000.0000000000001p
.model jjk jj(rtype=0,cct=1,icrit=0.32910597599999997u,cap=325.81491624f,force=1,vm=9.9
* SPICE Simulation
R1 1 0 50.0
L1 1 0 1000.0000000000001p
Lj1 2 0 1000.0000000000001p
K1 L1 L2 0.1
L2 2 0 1000.0000000000001p
C2 2 0 2000.0f
@variables Rleft L1 K1 L2 C2 C3 Lj1
circuit = Vector{Tuple{String,String,String,Num}}(undef,0)
push!(circuit,("P1","1","0",1))
push!(circuit,("R1","1","0",Rleft))
push!(circuit,("L1","1","0",L1))
push!(circuit,("Lj1","2","0",Lj1))
push!(circuit,("K1","L2","L1",K1))
push!(circuit,("L2","2","0",L2))
push!(circuit,("C2","2","0",C2))
push!(circuit,("C3","2","0",C3))
circuitdefs = Dict(
Rleft => 50.0,
L1 => 1000.0e-12,
Lj1 => 1000.0e-12,
K1 => 0.1,
L2 => 1000.0e-12,
C2 => 1000.0e-15,
C3 => 1000.0e-15)
println(JosephsonCircuits.exportnetlist(circuit, circuitdefs;port = 1, jj = true).netlist)
println("")
println(JosephsonCircuits.exportnetlist(circuit, circuitdefs;port = 1, jj = false).netlist)
# output
* SPICE Simulation
R1 1 0 50.0
L1 1 0 1000.0000000000001p
B1 2 0 3 jjk ics=0.32910597599999997u
C2 2 0 1674.18508376f
K1 L2 L1 0.1
L2 2 0 1000.0000000000001p
.model jjk jj(rtype=0,cct=1,icrit=0.32910597599999997u,cap=325.81491624f,force=1,vm=9.9
* SPICE Simulation
R1 1 0 50.0
L1 1 0 1000.0000000000001p
Lj1 2 0 1000.0000000000001p
K1 L2 L1 0.1
L2 2 0 1000.0000000000001p
C2 2 0 2000.0f
JosephsonCircuits.extractbranches!
— Methodextractbranches!(branchvector::Vector,componenttypes::Vector{Symbol},
nodeindexarray::Matrix{Int})
Append tuples consisting of a pair of node indices (branches) which we will use to calculate the incidence matrix. Appends the tuples to branchvector.
JosephsonCircuits.extractbranches
— Methodextractbranches(componenttypes::Vector{Symbol},nodeindexarray::Matrix{Int})
Return an array of tuples of pairs of node indices (branches) which we will use to calculate the incidence matrix.
This will contain duplicates if multiple components are on the same branch. All checking for duplicate branches will occur in the graph procesing code.
NOTE: the list of component types considered to lie on branches is hardcoded.
Examples
julia> JosephsonCircuits.extractbranches([:P,:I,:R,:C,:Lj,:C],[2 2 2 2 3 3; 1 1 1 3 1 1])
3-element Vector{Tuple{Int64, Int64}}:
(2, 1)
(2, 1)
(3, 1)
JosephsonCircuits.find_duplicate_connections
— Methodfind_duplicate_connections(
connections::AbstractVector{Tuple{T,T,Int,Int}}) where {T}
Return a vector of tuples of (connection, counts) where counts is the number of times a given connection appears.
JosephsonCircuits.find_duplicate_network_names
— Methodfind_duplicate_network_names(
networks::AbstractVector{Tuple{T,N,Vector{Tuple{T, Int}}}}) where {T,N}
Return a vector of tuples of (networkname, counts) where counts is the number of times a given network name appears.
JosephsonCircuits.findgroundnodeindex
— Methodfindgroundnodeindex(uniquenodevector::Vector{String})
Find the index of the ground node.
Examples
julia> JosephsonCircuits.findgroundnodeindex(["1","0","2"])
2
julia> JosephsonCircuits.findgroundnodeindex(["1","2"])
0
julia> JosephsonCircuits.findgroundnodeindex(String[])
0
JosephsonCircuits.fourierindices
— Methodfourierindices(freq::Frequencies)
Generate the indices used in the RDFT or DFT and inverse RDFT or DFT and converting between a node flux vector for solving system and the matrices for the Fourier analysis. See also FourierIndices
, Frequencies
, calcfreqsrdft
and calcfreqsdft
.
JosephsonCircuits.freqsubst
— Methodfreqsubst(A::SparseMatrixCSC, wmodes::Vector, symfreqvar)
Substitute the frequency dependent elements of A
using the vector of mode frequencies wmodes
and the symbolic frequency variable symfreqvar
. Returns a sparse matrix with type Complex{Float64}
.
Examples
@variables w
wmodes = [-1,2];
A = JosephsonCircuits.diagrepeat(JosephsonCircuits.SparseArrays.sparse([1,2,1], [1,2,2], [w,2*w,3*w],2,2),2);
JosephsonCircuits.freqsubst(A,wmodes,w)
# output
4×4 SparseArrays.SparseMatrixCSC{ComplexF64, Int64} with 6 stored entries:
-1.0+0.0im ⋅ -3.0+0.0im ⋅
⋅ 2.0+0.0im ⋅ 6.0+0.0im
⋅ ⋅ -2.0+0.0im ⋅
⋅ ⋅ ⋅ 4.0+0.0im
wmodes = [-1,2];
A = JosephsonCircuits.diagrepeat(JosephsonCircuits.SparseArrays.sparse([1,2,1], [1,2,2], [1,2,3],2,2),2);
JosephsonCircuits.freqsubst(A,wmodes,nothing)
# output
4×4 SparseArrays.SparseMatrixCSC{ComplexF64, Int64} with 6 stored entries:
1.0+0.0im ⋅ 3.0+0.0im ⋅
⋅ 1.0+0.0im ⋅ 3.0+0.0im
⋅ ⋅ 2.0+0.0im ⋅
⋅ ⋅ ⋅ 2.0+0.0im
JosephsonCircuits.frequencyscale
— Methodfrequencyscale(frequencyunit::String)
Convert the SI prefix in the string frequencyunit
to the corresponding numerical value.
Examples
julia> JosephsonCircuits.frequencyscale("MHz")
1.0e6
JosephsonCircuits.get_ports
— Methodget_ports(network::Tuple{T, N, Vector{Tuple{T, Int}}}) where {T,N}
Return the ports for a network network
. The ports are already present in the network.
Examples
julia> JosephsonCircuits.get_ports((:S1,[0.0 1.0;1.0 0.0],[(:S1,1),(:S2,3)]))
2-element Vector{Tuple{Symbol, Int64}}:
(:S1, 1)
(:S2, 3)
JosephsonCircuits.get_ports
— Methodget_ports(network::Tuple{T, N}) where {T,N}
Return the ports for a network network
. The ports are generated based on the network name.
Examples
julia> JosephsonCircuits.get_ports((:S1,[0.0 1.0;1.0 0.0]))
2-element Vector{Tuple{Symbol, Int64}}:
(:S1, 1)
(:S1, 2)
JosephsonCircuits.hblinsolve
— Methodhblinsolve(w, circuit,circuitdefs; Nmodulationharmonics = (0,),
nonlinear=nothing, symfreqvar=nothing, threewavemixing=false,
fourwavemixing=true, maxintermodorder=Inf,
nbatches::Integer = Base.Threads.nthreads(), returnS = true,
returnSnoise = false, returnQE = true, returnCM = true,
returnnodeflux = false, returnnodefluxadjoint = false,
returnvoltage = false,
)
Harmonic balance solver supporting an arbitrary number of small signals (weak tones) linearized around pump
, the solution of the nonlinear system consisting of an arbitrary number of large signals (strong tones).
Arguments
w
:circuit
:circuitdefs
:
Keywords
Nmodulationharmonics = (0,)
:nonlinear=nothing
:symfreqvar=nothing
:threewavemixing=false
:fourwavemixing=true
:maxintermodorder=Inf
:nbatches::Integer = Base.Threads.nthreads()
:returnS = true
:returnSnoise = false
:returnQE = true
:returnCM = true
:returnnodeflux = false
:returnnodefluxadjoint = false
:returnvoltage = false
:
Returns
LinearizedHB
: A simple structure to hold the harmonic balance solutions. SeeLinearizedHB
.
Examples
circuit = Tuple{String,String,String,Union{Complex{Float64},Symbol,Int64}}[]
push!(circuit,("P1","1","0",1))
push!(circuit,("R1","1","0",:Rleft))
push!(circuit,("L1","1","0",:Lm))
push!(circuit,("K1","L1","L2",:K1))
push!(circuit,("C1","1","2",:Cc))
push!(circuit,("L2","2","3",:Lm))
push!(circuit,("Lj3","3","0",:Lj))
push!(circuit,("Lj4","2","0",:Lj))
push!(circuit,("C2","2","0",:Cj))
circuitdefs = Dict{Symbol,Complex{Float64}}(
:Lj =>2000e-12,
:Lm =>10e-12,
:Cc => 200.0e-15,
:Cj => 900e-15,
:Rleft => 50.0,
:Rright => 50.0,
:K1 => 0.9,
)
Idc = 1e-6*0
Ip=5.0e-6
wp=2*pi*5e9
ws=2*pi*5.2e9
symfreqvar = nothing
# modulation settings
Npumpharmonics = (16,)
Nmodulationharmonics = (2,)
threewavemixing=false
fourwavemixing=true
nonlinear=hbnlsolve(
(wp,),
Npumpharmonics,
[
(mode=(0,),port=1,current=Idc),
(mode=(1,),port=1,current=Ip),
],
circuit,circuitdefs;dc=true,odd=fourwavemixing,even=threewavemixing)
linearized = JosephsonCircuits.hblinsolve(ws,
circuit, circuitdefs; Nmodulationharmonics = Nmodulationharmonics,
nonlinear = nonlinear, symfreqvar=nothing, threewavemixing=false,
fourwavemixing=true, returnnodeflux=true, keyedarrays = Val(false))
isapprox(linearized.nodeflux,
ComplexF64[9.901008591291e-12 - 6.40587007644028e-14im 2.164688307719963e-14 - 2.90852607344097e-16im 6.671563044645655e-14 - 8.585524364135119e-16im; 2.1633104519765224e-14 - 8.251861334047893e-16im 1.0099063486905209e-11 - 1.948847859339803e-13im -8.532003011745068e-15 + 3.234788465760295e-16im; 6.671648606599472e-14 + 7.892709980649199e-16im -8.53757633177974e-15 - 9.748395563374129e-17im 9.856580758892428e-12 + 5.859984004390703e-14im; 1.5888896262186103e-11 - 1.0303480614499543e-13im -2.557126237504446e-12 + 1.759201163407723e-14im -8.475819811683215e-12 + 5.3531443609574795e-14im; -2.5781681021577177e-13 + 4.757590640631487e-15im 2.36818731889176e-12 - 4.569646499606389e-14im 1.116372367616482e-13 - 2.039935997276492e-15im; -1.0210743447568219e-11 - 5.905490368441375e-14im 1.3377918536056493e-12 + 7.190105205618706e-15im 2.5392856657302323e-11 + 1.5143842454586225e-13im; 2.4781693042536835e-11 - 1.6057018472176702e-13im -2.5342360504077476e-12 + 1.7306764301173096e-14im -8.40554044664581e-12 + 5.269404591748149e-14im; -2.348528974341763e-13 + 3.949450668269274e-15im 1.1449271118157543e-11 - 2.2093702114766968e-13im 1.0261871618968225e-13 - 1.7240213938923877e-15im; -1.0140560031409567e-11 - 5.828587508192886e-14im 1.3288225860409326e-12 + 7.0954601524623594e-15im 3.423954321087654e-11 + 2.0403371894291513e-13im],
atol = 1e-6)
# output
true
JosephsonCircuits.hblinsolve
— Methodhblinsolve(w, psc::ParsedSortedCircuit,
cg::CircuitGraph, circuitdefs, signalfreq::Frequencies{N};
nonlinear=nothing, symfreqvar=nothing,
nbatches::Integer = Base.Threads.nthreads(), sorting = :number,
returnS = true, returnSnoise = false, returnQE = true, returnCM = true,
returnnodeflux = false, returnnodefluxadjoint = false,
returnvoltage = false,
)
Harmonic balance solver supporting an arbitrary number of small signals (weak tones) linearized around pump
, the solution of the nonlinear system consisting of an arbitrary number of large signals (strong tones).
Examples
circuit = Tuple{String,String,String,Union{Complex{Float64},Symbol,Int64}}[]
push!(circuit,("P1","1","0",1))
push!(circuit,("R1","1","0",:Rleft))
push!(circuit,("L1","1","0",:Lm))
push!(circuit,("K1","L1","L2",:K1))
push!(circuit,("C1","1","2",:Cc))
push!(circuit,("L2","2","3",:Lm))
push!(circuit,("Lj3","3","0",:Lj))
push!(circuit,("Lj4","2","0",:Lj))
push!(circuit,("C2","2","0",:Cj))
circuitdefs = Dict{Symbol,Complex{Float64}}(
:Lj =>2000e-12,
:Lm =>10e-12,
:Cc => 200.0e-15,
:Cj => 900e-15,
:Rleft => 50.0,
:Rright => 50.0,
:K1 => 0.9,
)
Idc = 1e-6*0
Ip = 5.0e-6
wp = 2*pi*5e9
ws = 2*pi*5.2e9
Npumpharmonics = (2,)
Nmodulationharmonics = (2,)
threewavemixing = false
fourwavemixing = true
frequencies = JosephsonCircuits.removeconjfreqs(
JosephsonCircuits.truncfreqs(
JosephsonCircuits.calcfreqsrdft(Npumpharmonics),
dc = true, odd = true, even = false, maxintermodorder = Inf,
)
)
fi = JosephsonCircuits.fourierindices(frequencies)
Nmodes = length(frequencies.modes)
psc = JosephsonCircuits.parsesortcircuit(circuit)
cg = JosephsonCircuits.calccircuitgraph(psc)
nm = JosephsonCircuits.numericmatrices(psc, cg, circuitdefs, Nmodes = Nmodes)
nonlinear = hbnlsolve(
(wp,),
[
(mode=(0,),port=1,current=Idc),
(mode=(1,),port=1,current=Ip),
],
frequencies, fi, psc, cg, nm)
signalfreq =JosephsonCircuits.truncfreqs(
JosephsonCircuits.calcfreqsdft(Nmodulationharmonics),
dc = true, odd = threewavemixing, even = fourwavemixing,
maxintermodorder = Inf,
)
linearized = JosephsonCircuits.hblinsolve(ws, psc, cg, circuitdefs,
signalfreq;nonlinear = nonlinear, returnnodeflux=true, keyedarrays = Val(false))
isapprox(linearized.nodeflux,
ComplexF64[9.901008591291e-12 - 6.40587007644028e-14im 2.164688307719963e-14 - 2.90852607344097e-16im 6.671563044645655e-14 - 8.585524364135119e-16im; 2.1633104519765224e-14 - 8.251861334047893e-16im 1.0099063486905209e-11 - 1.948847859339803e-13im -8.532003011745068e-15 + 3.234788465760295e-16im; 6.671648606599472e-14 + 7.892709980649199e-16im -8.53757633177974e-15 - 9.748395563374129e-17im 9.856580758892428e-12 + 5.859984004390703e-14im; 1.5888896262186103e-11 - 1.0303480614499543e-13im -2.557126237504446e-12 + 1.759201163407723e-14im -8.475819811683215e-12 + 5.3531443609574795e-14im; -2.5781681021577177e-13 + 4.757590640631487e-15im 2.36818731889176e-12 - 4.569646499606389e-14im 1.116372367616482e-13 - 2.039935997276492e-15im; -1.0210743447568219e-11 - 5.905490368441375e-14im 1.3377918536056493e-12 + 7.190105205618706e-15im 2.5392856657302323e-11 + 1.5143842454586225e-13im; 2.4781693042536835e-11 - 1.6057018472176702e-13im -2.5342360504077476e-12 + 1.7306764301173096e-14im -8.40554044664581e-12 + 5.269404591748149e-14im; -2.348528974341763e-13 + 3.949450668269274e-15im 1.1449271118157543e-11 - 2.2093702114766968e-13im 1.0261871618968225e-13 - 1.7240213938923877e-15im; -1.0140560031409567e-11 - 5.828587508192886e-14im 1.3288225860409326e-12 + 7.0954601524623594e-15im 3.423954321087654e-11 + 2.0403371894291513e-13im],
atol = 1e-6)
# output
true
JosephsonCircuits.hblinsolve_inner!
— Methodhblinsolve_inner!(S, Snoise, QE, CM, nodeflux, voltage, Asparse,
AoLjnm, invLnm, Cnm, Gnm, bnm,
AoLjnmindexmap, invLnmindexmap, Cnmindexmap, Gnmindexmap,
Cnmfreqsubstindices, Gnmfreqsubstindices, invLnmfreqsubstindices,
portindices, portimpedanceindices, noiseportimpedanceindices,
portimpedances, noiseportimpedances, nodeindices, componenttypes,
w, indices, wp, Nmodes, Nnodes, symfreqvar, wi, factorization)
Solve the linearized harmonic balance problem for a subset of the frequencies given by wi
. This function is thread safe in that different frequencies can be computed in parallel on separate threads.
JosephsonCircuits.hblinsolveold
— Methodhblinsolveold(w, circuit, circuitdefs; wp = 0.0, Nmodes = 1,
Am = zeros(Complex{Float64},0,0), symfreqvar = nothing,
nbatches = Base.Threads.nthreads(), sorting = :number, returnS = true,
returnSnoise = false, returnQE = true, returnCM = true,
returnnodeflux = false, returnvoltage = false)
Linearized harmonic balance solver for single-pump four wave mixing processes in circuits containing Josephson junctions, capacitors, inductors, and resistors. Dissipation can be included through frequency dependent resistors or complex capacitance.
Returns user specified scattering parameters, quantum efficiency, and node fluxes or voltages.
Arguments
w
: signal frequency or vector of signal frequencies in radians/second.circuit
: vector of tuples containing component names, nodes, and values.circuitdefs
: dictionary defining the numerical values of circuit components.
Keywords
wp = 0.0
: pump frequency in radians/second. This function only supports a single pump frequency.Nmodes = 1
: number of signal and idler modes.Am = zeros(Complex{Float64},0,0)
:symfreqvar = nothing
: symbolic frequency variable which is set tonothing
by default but should be set equal to the frequency variable likew
if there is frequency dependence.nbatches = Base.Threads.nthreads()
: for the linearized harmonic balance solution, split the solutions for different frequencies into this many batches. Set equal to the number of threads. Recommend configuring Julia to use Sys.CPU_THREADS/2 threads.sorting = :number
: sort the ports by turning them into integers and sorting those integers. Seesortnodes
for other options if this fails.returnS = true
: iftrue
, return the scattering parameters for each set of ports and signal and idler frequencies.returnSnoise = false
: iftrue
, return the scattering parameters corresponding to inputs at the noise ports (lossy components) and outputs at the physical ports for the signal and idler frequencies.returnQE = true
: iftrue
, return the quantum efficiency for each signal and idler at each combinaton of ports.returnCM = true
: iftrue
, return the commutation relations for each signal and idler at each combinaton of ports (should equal ±1).returnnodeflux = false
: iftrue
, return the node fluxes for each signal and idler at each node. Set tofalse
by default to reduce memory usage.returnnodefluxadjoint = false
: iftrue
, return the node fluxes adjoint for each signal and idler at each node. Set tofalse
by default to reduce memory usage.returnvoltage = false
: iftrue
, return the node voltages for each signal and idler at each node. Set tofalse
by default to reduce memory usage.
Examples
@variables Rleft Cc Lj Cj w L1
circuit = Tuple{String,String,String,Num}[]
push!(circuit,("P1","1","0",1))
push!(circuit,("R1","1","0",Rleft))
push!(circuit,("C1","1","2",Cc))
push!(circuit,("Lj1","2","0",Lj))
push!(circuit,("C2","2","0",Cj))
circuitdefs = Dict(
Lj =>1000.0e-12,
Cc => 100.0e-15,
Cj => 1000.0e-15,
Rleft => 50.0,
)
w = 2*pi*(4.5:0.01:5.0)*1e9
result=JosephsonCircuits.hblinsolveold(w, circuit, circuitdefs)
using Plots;plot(w/(2*pi*1e9),angle.(result.S[:]))
JosephsonCircuits.hbmatind
— Methodhbmatind(truncfrequencies::Frequencies{N})
Returns a matrix describing which indices of the frequency domain matrix (from the RFFT) to pull out and use in the harmonic balance matrix. A negative index means we take the complex conjugate of that element. A zero index means that term is not present, so skip it. The harmonic balance matrix describes the coupling between different frequency modes.
Examples
julia> freq = JosephsonCircuits.calcfreqsrdft((5,));JosephsonCircuits.hbmatind(JosephsonCircuits.removeconjfreqs(JosephsonCircuits.truncfreqs(freq;dc=false,odd=true,even=false,maxintermodorder=2)))[2]
3×3 Matrix{Int64}:
1 -3 -5
3 1 -3
5 3 1
julia> freq = JosephsonCircuits.calcfreqsrdft((3,));JosephsonCircuits.hbmatind(JosephsonCircuits.removeconjfreqs(JosephsonCircuits.truncfreqs(freq;dc=true,odd=true,even=true,maxintermodorder=2)))[2]
4×4 Matrix{Int64}:
1 -2 -3 -4
2 1 -2 -3
3 2 1 -2
4 3 2 1
julia> freq = JosephsonCircuits.calcfreqsrdft((2,2));JosephsonCircuits.hbmatind(JosephsonCircuits.removeconjfreqs(JosephsonCircuits.truncfreqs(freq;dc=true,odd=true,even=true,maxintermodorder=2)))[1]
7×7 Matrix{Tuple{Int64, Int64}}:
(0, 0) (-1, 0) (-2, 0) (0, -1) (-1, -1) (0, -2) (-1, 1)
(1, 0) (0, 0) (-1, 0) (1, -1) (0, -1) (1, -2) (0, 1)
(2, 0) (1, 0) (0, 0) (2, -1) (1, -1) (2, -2) (1, 1)
(0, 1) (-1, 1) (-2, 1) (0, 0) (-1, 0) (0, -1) (-1, 2)
(1, 1) (0, 1) (-1, 1) (1, 0) (0, 0) (1, -1) (0, 2)
(0, 2) (-1, 2) (-2, 2) (0, 1) (-1, 1) (0, 0) (-1, 3)
(1, -1) (0, -1) (-1, -1) (1, -2) (0, -2) (1, -3) (0, 0)
julia> freq = JosephsonCircuits.calcfreqsrdft((2,2));JosephsonCircuits.hbmatind(JosephsonCircuits.removeconjfreqs(JosephsonCircuits.truncfreqs(freq;dc=true,odd=true,even=true,maxintermodorder=2)))[2]
7×7 Matrix{Int64}:
1 -2 -3 13 -5 10 -14
2 1 -2 14 13 11 4
3 2 1 15 14 12 5
4 -14 -15 1 -2 13 -11
5 4 -14 2 1 14 7
7 -11 -12 4 -14 1 0
14 13 -5 11 10 0 1
JosephsonCircuits.hbmatind
— Methodhbmatind(frequencies::Frequencies{N},
truncfrequencies::Frequencies{N})
Returns a matrix describing which indices of the frequency domain matrix (from the RFFT or FFT) to pull out and use in the harmonic balance matrix. A negative index means we take the complex conjugate of that element. A zero index means that term is not present, so skip it. The harmonic balance matrix describes the coupling between different frequency modes.
Examples
pumpfreq = JosephsonCircuits.truncfreqs(
JosephsonCircuits.calcfreqsrdft((4,)))
signalfreq = JosephsonCircuits.truncfreqs(
JosephsonCircuits.calcfreqsdft((4,));
dc=false,odd=true,even=false,maxintermodorder=2,
)
JosephsonCircuits.hbmatind(pumpfreq, signalfreq)[2]
# output
4×4 Matrix{Int64}:
1 -3 5 3
3 1 0 5
-5 0 1 -3
-3 -5 3 1
JosephsonCircuits.hbnlsolve
— Methodhbnlsolve(w::NTuple{N,Any}, sources, frequencies::Frequencies{N},
indices::FourierIndices{N}, psc::ParsedSortedCircuit, cg::CircuitGraph,
nm::CircuitMatrices; iterations = 1000, x0 = nothing,
ftol = 1e-8, switchofflinesearchtol = 1e-5, alphamin = 1e-4,
symfreqvar = nothing)
New version of the nonlinear harmonic balance solver suitable for arbitrary numbers of ports, sources, and drives including direct current (zero frequency) or flux pumping using a current source and a mutual inductor.
Examples
circuit = Tuple{String,String,String,Union{Complex{Float64},Symbol,Int64}}[]
push!(circuit,("P1","1","0",1))
push!(circuit,("R1","1","0",:Rleft))
push!(circuit,("L1","1","0",:Lm))
push!(circuit,("K1","L1","L2",:K1))
push!(circuit,("C1","1","2",:Cc))
push!(circuit,("L2","2","3",:Lm))
push!(circuit,("Lj3","3","0",:Lj))
push!(circuit,("Lj4","2","0",:Lj))
push!(circuit,("C2","2","0",:Cj))
circuitdefs = Dict{Symbol,Complex{Float64}}(
:Lj =>2000e-12,
:Lm =>10e-12,
:Cc => 200.0e-15,
:Cj => 900e-15,
:Rleft => 50.0,
:Rright => 50.0,
:K1 => 0.9,
)
Idc = 50e-5
Ip=0.0001e-6
wp=2*pi*5e9
Nharmonics = (2,)
frequencies = JosephsonCircuits.removeconjfreqs(
JosephsonCircuits.truncfreqs(
JosephsonCircuits.calcfreqsrdft(Nharmonics),
dc=true, odd=true, even=false, maxintermodorder=Inf,
)
)
fi = JosephsonCircuits.fourierindices(frequencies)
Nmodes = length(frequencies.modes)
psc = JosephsonCircuits.parsesortcircuit(circuit)
cg = JosephsonCircuits.calccircuitgraph(psc)
nm = JosephsonCircuits.numericmatrices(psc, cg, circuitdefs, Nmodes = Nmodes)
out=hbnlsolve(
(wp,),
[
(mode=(0,),port=1,current=Idc),
(mode=(1,),port=1,current=Ip),
],
frequencies, fi, psc, cg, nm)
isapprox(out.nodeflux[:],
ComplexF64[15.190314040027522 - 8.56492651167657e-24im, 2.991103820177504e-6 - 1.8501001011477133e-8im, -6.835392148510984 - 1.0356102442254259e-14im, 7.396422335315908e-6 - 4.5749403967992827e-8im, 6.835392148539885 - 1.0356102451770844e-14im, 1.008026285172782e-5 - 6.23498762664213e-8im],
atol = 1e-6)
# output
true
JosephsonCircuits.hbnlsolve
— Methodhbnlsolve(w::NTuple{N,Any}, Nharmonics::NTuple{N,Int}, sources,
circuit, circuitdefs; iterations = 1000,
maxintermodorder = Inf, dc = false, odd = true, even = false,
x0 = nothing, ftol = 1e-8, switchofflinesearchtol = 1e-5,
alphamin = 1e-4, symfreqvar = nothing, sorting= :number)
New version of the nonlinear harmonic balance solver suitable for arbitrary numbers of ports, sources, and drives including direct current (zero frequency) or flux pumping using a current source and a mutual inductor.
Arguments
w::NTuple{N,Any}
:Nharmonics::NTuple{N,Int}
:sources
:circuit
:circuitdefs
:
Keywords
iterations = 1000
:maxintermodorder = Inf
:dc = false
:odd = true
:even = false
:x0 = nothing
:ftol = 1e-8
:switchofflinesearchtol = 1e-5
:alphamin = 1e-4
:symfreqvar = nothing
:sorting= :number
:
Returns
NonlinearHB
: A simple structure to hold the harmonic balance solutions. SeeNonlinearHB
.
Examples
circuit = Tuple{String,String,String,Union{Complex{Float64},Symbol,Int64}}[]
push!(circuit,("P1","1","0",1))
push!(circuit,("R1","1","0",:Rleft))
push!(circuit,("L1","1","0",:Lm))
push!(circuit,("K1","L1","L2",:K1))
push!(circuit,("C1","1","2",:Cc))
push!(circuit,("L2","2","3",:Lm))
push!(circuit,("Lj3","3","0",:Lj))
push!(circuit,("Lj4","2","0",:Lj))
push!(circuit,("C2","2","0",:Cj))
circuitdefs = Dict{Symbol,Complex{Float64}}(
:Lj =>2000e-12,
:Lm =>10e-12,
:Cc => 200.0e-15,
:Cj => 900e-15,
:Rleft => 50.0,
:Rright => 50.0,
:K1 => 0.9,
)
Idc = 50e-5
Ip=0.0001e-6
wp=2*pi*5e9
Npumpmodes = 2
out=hbnlsolve(
(wp,),
(Npumpmodes,),
[
(mode=(0,),port=1,current=Idc),
(mode=(1,),port=1,current=Ip),
],
circuit,circuitdefs;dc=true,odd=true,even=false)
isapprox(out.nodeflux[:],
ComplexF64[15.190314040027522 - 8.56492651167657e-24im, 2.991103820177504e-6 - 1.8501001011477133e-8im, -6.835392148510984 - 1.0356102442254259e-14im, 7.396422335315908e-6 - 4.5749403967992827e-8im, 6.835392148539885 - 1.0356102451770844e-14im, 1.008026285172782e-5 - 6.23498762664213e-8im],
atol = 1e-6)
# output
true
JosephsonCircuits.hbnlsolveold
— Methodhbnlsolveold(wp, Ip, Nmodes, circuit, circuitdefs; ports = [1],
iterations = 1000, ftol = 1e-8, symfreqvar = nothing,
sorting = :number)
Nonlinear harmonic balance solver for single-pump four wave mixing processes in circuits containing Josephson junctions, capacitors, inductors, and resistors. Dissipation can be included through frequency dependent resistors or complex capacitance.
Arguments
wp
: pump frequency in radians/second. This function only supports a single pump frequency.Ip
: pump current or vector of pump currents in amps. Length ofIp
must be equal to length ofports
.Nmodes
: number of modes (harmonics).circuit
: vector of tuples containing component names, nodes, and values.circuitdefs
: dictionary defining the numerical values of circuit components.
Keywords
ports = [1]
: vector of drive port numbers. Default is a single drive at port 1.iterations = 1000
: number of iterations at which the nonlinear solver stops even if convergence criteria not reached.ftol = 1e-8
: relative or absolute tolerance at which nonlinear solver stops (whichever is reached first).symfreqvar = nothing
: symbolic frequency variable which is set tonothing
by default but should be set equal to the frequency variable likew
if there is frequency dependence.sorting = :number
: sort the ports by turning them into integers and sorting those integers. Seesortnodes
for other options if this fails.
Examples
@variables Rleft Cc Lj Cj w L1
circuit = Tuple{String,String,String,Num}[]
push!(circuit,("P1","1","0",1))
push!(circuit,("R1","1","0",Rleft))
push!(circuit,("C1","1","2",Cc))
push!(circuit,("Lj1","2","0",Lj))
push!(circuit,("C2","2","0",Cj))
circuitdefs = Dict(
Lj =>1000.0e-12,
Cc => 100.0e-15,
Cj => 1000.0e-15,
Rleft => 50.0,
)
wp = 2*pi*4.75001*1e9
Ip = 0.00565e-6
Nmodes = 8
hbnlsolve(wp, Ip, Nmodes, circuit, circuitdefs, ports=[1])
JosephsonCircuits.hbsolve
— Methodhbsolve(ws, wp, Ip, Nsignalmodes, Npumpmodes, circuit, circuitdefs;
pumpports = [1], iterations = 1000, ftol = 1e-8,
switchofflinesearchtol = 1e-5, alphamin = 1e-4,
symfreqvar = nothing, nbatches = Base.Threads.nthreads(),
sorting = :number, returnS = true, returnSnoise = false,
returnQE = true, returnCM = true, returnnodeflux = false,
returnvoltage = false, returnnodefluxadjoint = false,
)
Calls the new harmonic balance solvers, hbnlsolve
and hblinsolve
, which work for an arbitrary number of modes and ports), using an identical syntax to hbsolveold
, which only supports four wave mixing processes involving single strong tone and an arbitrary number of tone in the linearized solver. This function is primarily for testing the new solvers and will eventually be deprecated.
This function attempts to mimic hbsolveold
, but with the difference: The outputs of the linearized harmonic balance solver hblinsolve
may not have the same ordering of signal modes as in hblinsolveold
. In hblinsolve
the signal mode is always at index 1 and the location of the other modes can be found by inspecting the contents of modes
.
JosephsonCircuits.hbsolve
— Methodhbsolve(ws, wp::NTuple{N,Any}, sources::Vector,
Nmodulationharmonics::NTuple{M,Any}, Npumpharmonics::NTuple{N,Any},
circuit, circuitdefs; dc = false, threewavemixing = false,
fourwavemixing = true, maxintermodorder=Inf, iterations = 1000,
ftol = 1e-8, switchofflinesearchtol = 1e-5, alphamin = 1e-4,
symfreqvar = nothing, nbatches = Base.Threads.nthreads(),
sorting = :number, returnS = true, returnSnoise = false,
returnQE = true, returnCM = true, returnnodeflux = false,
returnvoltage = false, returnnodefluxadjoint = false,
returnvoltageadjoint = false, keyedarrays::Val{K} = Val(true),
sensitivitynames = String[], returnSsensitivity = false,
returnZ = false, returnZadjoint = false,
returnZsensitivity = false, returnZsensitivityadjoint = false)
Arguments
ws
:wp::NTuple{N,Any}
:sources::Vector
:Nmodulationharmonics::NTuple{M,Any}
:Npumpharmonics::NTuple{N,Any}
:circuit
:circuitdefs
:
Keywords
dc = false
:threewavemixing = false
:fourwavemixing = true
:maxintermodorder=Inf
:iterations = 1000
:ftol = 1e-8
:switchofflinesearchtol = 1e-5
:alphamin = 1e-4
:symfreqvar = nothing
:nbatches = Base.Threads.nthreads()
:sorting = :number
:returnS = true
:returnSnoise = false
:returnQE = true
:returnCM = true
:returnnodeflux = false
:returnvoltage = false
:returnnodefluxadjoint = false
:returnvoltageadjoint = false
:keyedarrays::Val{K} = Val(true)
:sensitivitynames = String[]
:returnSsensitivity = false
:returnZ = false
:returnZadjoint = false
:returnZsensitivity = false
:returnZsensitivityadjoint = false
:
Returns
HB
: A simple structure to hold the harmonic balance solutions. SeeHB
.
JosephsonCircuits.hbsolveold
— Methodhbsolveold(ws, wp, Ip, Nsignalmodes, Npumpmodes, circuit, circuitdefs;
pumpports = [1], iterations = 1000, ftol = 1e-8,
symfreqvar = nothing, nbatches = Base.Threads.nthreads(),
sorting = :number, returnS = true, returnSnoise = false,
returnQE = true, returnCM = true, returnnodeflux = false,
returnvoltage = false)
Harmonic balance solver for single-pump four wave mixing processes in circuits containing Josephson junctions, capacitors, inductors, and resistors. Dissipation can be included through frequency dependent resistors or complex capacitance.
Returns user specified scattering parameters, quantum efficiency, and node fluxes or voltages.
Arguments
ws
: signal frequency or vector of signal frequencies in radians/second.wp
: pump frequency in radians/second. This function only supports a single pump frequency.Ip
: pump current or vector of pump currents in amps. Length ofIp
must be equal to length ofpumpports
.Nsignalmodes
: number of signal and idler modes.Npumpmodes
: number of pump modes (pump harmonics).circuit
: vector of tuples containing component names, nodes, and values.circuitdefs
: dictionary defining the numerical values of circuit components.
Keywords
pumpports = [1]
: vector of pump port numbers. Default is a single pump at port 1.iterations = 1000
: number of iterations at which the nonlinear solver stops even if convergence criteria not reached.ftol = 1e-8
: relative or absolute tolerance at which nonlinear solver stops (whichever is reached first).symfreqvar = nothing
: symbolic frequency variable which is set tonothing
by default but should be set equal to the frequency variable likew
if there is frequency dependence.nbatches = Base.Threads.nthreads()
: for the linearized harmonic balance solution,split the solutions for different frequencies into this many batches. Set equalt to the number of threads. Recommend configuring Julia to use Sys.CPU_THREADS/2 threads.sorting = :number
: sort the ports by turning them into integers and sorting those integers. Seesortnodes
for other options if this fails.returnS = true
: iftrue
, return the scattering parameters for each set of ports and signal and idler frequencies.returnSnoise = false
: iftrue
, return the scattering parameters corresponding to inputs at the noise ports (lossy components) and outputs at the physical ports for the signal and idler frequencies.returnQE = true
: iftrue
, return the quantum efficiency for each signal and idler at each combinaton of ports.returnCM = true
: iftrue
, return the commutation relations for each signal and idler at each combinaton of ports (should equal ±1).returnnodeflux = false
: iftrue
, return the node fluxes for each signal and idler at each node. Set tofalse
by default to reduce memory usage.returnnodefluxadjoint = false
: iftrue
, return the node fluxes adjoint for each signal and idler at each node. Set tofalse
by default to reduce memory usage.returnvoltage = false
: iftrue
, return the node voltages for each signal and idler at each node. Set tofalse
by default to reduce memory usage.
Examples
@variables Rleft Cc Lj Cj w L1
circuit = Tuple{String,String,String,Num}[]
push!(circuit,("P1","1","0",1))
push!(circuit,("R1","1","0",Rleft))
push!(circuit,("C1","1","2",Cc))
push!(circuit,("Lj1","2","0",Lj))
push!(circuit,("C2","2","0",Cj))
circuitdefs = Dict(
Lj =>1000.0e-12,
Cc => 100.0e-15,
Cj => 1000.0e-15,
Rleft => 50.0,
)
ws = 2*pi*(4.5:0.01:5.0)*1e9
wp = 2*pi*4.75001*1e9
Ip = 0.00565e-6
Nsignalmodes = 8
Npumpmodes = 8
result=JosephsonCircuits.hbsolveold(ws, wp, Ip, Nsignalmodes, Npumpmodes, circuit, circuitdefs,pumpports=[1])
using Plots;plot(ws/(2*pi*1e9),10*log10.(abs2.(result.signal.S[result.signal.signalindex,result.signal.signalindex,:])))
JosephsonCircuits.import_netlist!
— Methodimport_netlist!(io::IO, circuit)
Import the netlist from the IOBuffer or IOStream io
to the vector of tuples circuit
.
Examples
julia> io = IOBuffer();circuit1=[("P","1","0",1),("R","1","0",50.0)];JosephsonCircuits.export_netlist!(io,circuit1,Dict());circuit2 = Tuple{String,String,String,Num}[];JosephsonCircuits.import_netlist!(io,circuit2);circuit2
2-element Vector{Tuple{String, String, String, Num}}:
("P", "1", "0", 1.0)
("R", "1", "0", 50.0)
JosephsonCircuits.import_netlist
— Methodimport_netlist(filename)
Import the netlist from the IOBuffer or IOStream io
and return a vector of tuples representing the circuit.
JosephsonCircuits.isbegininformation
— Methodisbegininformation(line::String)
Return true
if the string line
is the [begin information] line of a Touchstone file.
Examples
julia> JosephsonCircuits.isbegininformation("[begin information]")
true
julia> JosephsonCircuits.isbegininformation("[version] 1.0")
false
JosephsonCircuits.isend
— Methodisend(line::String)
Return true
if the string line
is the [end] line of a Touchstone file.
Examples
julia> JosephsonCircuits.isend("[end]")
true
julia> JosephsonCircuits.isend("[version] 1.0")
false
JosephsonCircuits.isendinformation
— Methodisendinformation(line::String)
Return true
if the string line
is the [end information] line of a Touchstone file.
Examples
julia> JosephsonCircuits.isendinformation("[end information]")
true
julia> JosephsonCircuits.isendinformation("[version] 1.0")
false
JosephsonCircuits.ismatrixformat
— Methodismatrixformat(line::String)
Return true
if the string line
is the [matrix format] line of a Touchstone file.
Examples
julia> JosephsonCircuits.ismatrixformat("[matrix format] full")
true
julia> JosephsonCircuits.ismatrixformat("[version] 1.0")
false
JosephsonCircuits.ismixedmodeorder
— Methodismixedmodeorder(line::String)
Return true
if the string line
is the [mixed-mode order] line of a Touchstone file.
Examples
julia> JosephsonCircuits.ismixedmodeorder("[mixed-mode order] full")
true
julia> JosephsonCircuits.ismixedmodeorder("[version] 1.0")
false
JosephsonCircuits.isnetworkdata
— Methodisnetworkdata(line::String)
Return true
if the string line
is the [network data] line of a Touchstone file.
Examples
julia> JosephsonCircuits.isnetworkdata("[network data]")
true
julia> JosephsonCircuits.isnetworkdata("[version] 1.0")
false
JosephsonCircuits.isnoisedata
— Methodisnoisedata(line::String)
Return true
if the string line
is the [noise data] line of a Touchstone file.
Examples
julia> JosephsonCircuits.isnoisedata("[noise data]")
true
julia> JosephsonCircuits.isnoisedata("[version] 1.0")
false
JosephsonCircuits.isnumberoffrequencies
— Methodisnumberoffrequencies(line::String)
Return true
if the string line
is the [number of frequencies] line of a Touchstone file.
Examples
julia> JosephsonCircuits.isnumberoffrequencies("[number of frequencies]")
true
julia> JosephsonCircuits.isnumberoffrequencies("[version] 1.0")
false
JosephsonCircuits.isnumberofnoisefrequencies
— Methodisnumberofnoisefrequencies(line::String)
Return true
if the string line
is the [number of noise frequencies] line of a Touchstone file.
Examples
julia> JosephsonCircuits.isnumberofnoisefrequencies("[number of noise frequencies]")
true
julia> JosephsonCircuits.isnumberofnoisefrequencies("[version] 1.0")
false
JosephsonCircuits.isnumberofports
— Methodisnumberofports(line::String)
Return true
if the string line
is the [number of ports] line of a Touchstone file.
Examples
julia> JosephsonCircuits.isnumberofports("[number of ports] 1")
true
julia> JosephsonCircuits.isnumberofports("[version] 1.0")
false
JosephsonCircuits.isoptionline
— Methodisoptionline(line::String)
Return true
if the string line
is the option line of a Touchstone file.
Examples
julia> JosephsonCircuits.isoptionline("# MHz Z MA R 75")
true
julia> JosephsonCircuits.isoptionline("[number of ports] 1")
false
JosephsonCircuits.isreference
— Methodisreference(line::String)
Return true
if the string line
is the [reference] line of a Touchstone file.
Examples
julia> JosephsonCircuits.isreference("[reference]")
true
julia> JosephsonCircuits.isreference("[version] 1.0")
false
JosephsonCircuits.istwoportdataorder
— Methodistwoportdataorder(line::String)
Return true
if the string line
is the [two-port data order] line of a Touchstone file.
Examples
julia> JosephsonCircuits.istwoportdataorder("[two-port data order] 12_21")
true
julia> JosephsonCircuits.istwoportdataorder("[version] 1.0")
false
JosephsonCircuits.isversion
— Methodisversion(line::String)
Return true
if the string line
is the [version] line of a Touchstone file.
Examples
julia> JosephsonCircuits.isversion("[version] 1.0")
true
julia> JosephsonCircuits.isversion("[number of ports] 1")
false
JosephsonCircuits.keepfreqs
— Methodkeepfreqs(frequencies::Frequencies{N},
keepcoords::AbstractVector{CartesianIndex{N}})
Return a new Frequencies struct with all coordinates and modes except the ones in keepmodes removed.
Examples
julia> JosephsonCircuits.keepfreqs(JosephsonCircuits.calcfreqsrdft((2,)),CartesianIndex{1}[])
JosephsonCircuits.Frequencies{1}((2,), (3,), (4,), CartesianIndex{1}[], Tuple{Int64}[])
julia> JosephsonCircuits.keepfreqs(JosephsonCircuits.calcfreqsrdft((2,)),CartesianIndex{1}[CartesianIndex(1,)])
JosephsonCircuits.Frequencies{1}((2,), (3,), (4,), CartesianIndex{1}[CartesianIndex(1,)], [(0,)])
JosephsonCircuits.keepfreqs
— Methodkeepfreqs(frequencies::Frequencies{N},
keepmodes::AbstractVector{NTuple{N,Int}})
Return a new Frequencies struct with all coordinates and modes except the ones in keepmodes removed.
Examples
julia> JosephsonCircuits.keepfreqs(JosephsonCircuits.calcfreqsrdft((2,2)),[(0,0),(1,0),(0,1),(1,1)])
JosephsonCircuits.Frequencies{2}((2, 2), (3, 5), (4, 5), CartesianIndex{2}[CartesianIndex(1, 1), CartesianIndex(2, 1), CartesianIndex(1, 2), CartesianIndex(2, 2)], [(0, 0), (1, 0), (0, 1), (1, 1)])
julia> JosephsonCircuits.keepfreqs(JosephsonCircuits.calcfreqsrdft((2,2)),Tuple{Int64,Int64}[])
JosephsonCircuits.Frequencies{2}((2, 2), (3, 5), (4, 5), CartesianIndex{2}[], Tuple{Int64, Int64}[])
JosephsonCircuits.ldiv_2x2
— Methodldiv_2x2(fact,b)
Solve the linear system A*x = b for x using left division when given fact
which is the LU factorization of A
.
JosephsonCircuits.linesearch
— Methodlinesearch(f, fp, dfdalpha, alphamin)
Quadratic linesearch based on Nocedal and Wright, chapter 3 section 5. f
is the value at the first point alpha=0.0, fp
is the value at the second point, alpha=1.0, dfdalpha
is the derivative at the first point, and alphamin
is the minimum value of dfdalpha
below which we will take a full step. The linesearch will return the fitted minimum of the function with respect to alpha as (alpha at which minimum occurs, minimum value of function).
JosephsonCircuits.lu_2x2
— Methodlu_2x2(A)
Return the LU factorization of a 2 by 2 matrix as a StaticArrays.LU struct. Perform the LU factorization even if A
is singular.
JosephsonCircuits.make_connection!
— Methodmake_connection!(g,fconnectionlist,fweightlist,ports,networkdata,src_node,
connection_index)
Apply the connection specified by the source node src_node
and the index of the connection in the forward adjacency list connection_index
. Modify the arguments and return nothing.
JosephsonCircuits.matrixindices
— Methodmatrixindices(nports, format, twoportdataorder)
Return the cartesian indices of the elements of a scattering matrix given the number of ports nports
and the format format
which can be "Full", "Upper", or "Lower". The two port data order twoportdataorder
can be "12_21
" or "21_12
" for 2 ports but must be "12_21
" for other numbers of ports.
Examples
julia> JosephsonCircuits.matrixindices(2,"Full","12_21")
4-element Vector{CartesianIndex{2}}:
CartesianIndex(1, 1)
CartesianIndex(1, 2)
CartesianIndex(2, 1)
CartesianIndex(2, 2)
julia> JosephsonCircuits.matrixindices(2,"Full","21_12")
4-element Vector{CartesianIndex{2}}:
CartesianIndex(1, 1)
CartesianIndex(2, 1)
CartesianIndex(1, 2)
CartesianIndex(2, 2)
JosephsonCircuits.matrixindices
— Methodmatrixindices(nports, format)
Return the cartesian indices of the elements of a scattering matrix given the number of ports nports
and the format format
which can be "Full", "Upper", or "Lower".
Examples
julia> JosephsonCircuits.matrixindices(2,"Full",printflag=true)
11 12
21 22
4-element Vector{CartesianIndex{2}}:
CartesianIndex(1, 1)
CartesianIndex(1, 2)
CartesianIndex(2, 1)
CartesianIndex(2, 2)
julia> JosephsonCircuits.matrixindices(2,"Upper",printflag=true)
11 12
22
3-element Vector{CartesianIndex{2}}:
CartesianIndex(1, 1)
CartesianIndex(1, 2)
CartesianIndex(2, 2)
julia> JosephsonCircuits.matrixindices(2,"Lower",printflag=true)
11
21 22
3-element Vector{CartesianIndex{2}}:
CartesianIndex(1, 1)
CartesianIndex(2, 1)
CartesianIndex(2, 2)
JosephsonCircuits.maxwell_combine
— Methodmaxwell_combine(n::Int, d::Dict{NTuple{N, Int}, T}) where {N,T<:AbstractMatrix}
Return the Maxwell capacitance matrix for an n
terminal system from the Maxwell capacitance matrices for sets of terminals stored in the dictionary d
. The dictionary keys are tuples of the terminal numbers for the capacitance matrices and the values are the capacitance matrices.
Examples
julia> @variables C11, C12, C13, C21, C22, C23, C31, C32, C33;JosephsonCircuits.maxwell_combine(3, Dict((1,2)=>[C11 C12;C21 C22],(1,3)=>[C11 C13;C31 C33],(2,3)=>[C22 C23;C32 C33]))
3×3 Matrix{Num}:
C11 C12 C13
C21 C22 C23
C31 C32 C33
julia> @variables C11, C12, C13, C21, C22, C23, C31, C32, C33;JosephsonCircuits.maxwell_combine(3, Dict((1,2,3)=>[C11 C12 C13;C21 C22 C23; C31 C32 C33]))
3×3 Matrix{Num}:
C11 C12 C13
C21 C22 C23
C31 C32 C33
JosephsonCircuits.maxwell_to_even_odd
— Methodmaxwell_to_even_odd(L, Cmaxwell)
Return the even and odd mode impedances and the even and odd mode indices from the inductance matrix L
and the Maxwell capacitance matrix Cmaxwell
.
Examples
@variables C11, C12, L11, L12
C = [C11 C12;C12 C11]
L = [L11 L12;L12 L11]
Zeven, Zodd, neven, nodd = JosephsonCircuits.maxwell_to_even_odd(L,C)
@show Zeven
@show Zodd
@show neven
@show nodd
;
# output
Zeven = sqrt((L11 + L12) / (C11 + C12))
Zodd = sqrt((L11 - L12) / (C11 - C12))
neven = 2.99792458e8sqrt((C11 + C12)*(L11 + L12))
nodd = 2.99792458e8sqrt((C11 - C12)*(L11 - L12))
JosephsonCircuits.maxwell_to_mutual
— Methodmaxwell_to_mutual(Cmaxwell::AbstractMatrix)
Return the mutual capacitance matrix from the Maxwell capacitance matrix Cmaxwell
.
The Maxwell capacitance Cmaxwell
is the relationship between charge and voltage on each node, Q = C V or dQi/dVj = C_ij where C
is the Maxwell capacitance matrix.
Each element of the mutual capacitance matrix Cmutual
is the value of a physical capacitor placed between two nodes in a circuit or between a node and ground.
Examples
julia> @variables C11, C12, C21, C22;C = [C11 C12;C21 C22];JosephsonCircuits.maxwell_to_mutual(C)
2×2 Matrix{Num}:
C11 + C12 -C12
-C21 C21 + C22
julia> C = [1.0 -0.1;-0.1 2.0];JosephsonCircuits.maxwell_to_mutual(C)
2×2 Matrix{Float64}:
0.9 0.1
0.1 1.9
JosephsonCircuits.move_bedge!
— Methodmove_bedge!(g,dst_node,dst_node_new,edge_index,fadjlist1,fadjlist2)
Move an edge from graph g
at destination node dst_node
to the new destination node dst_node_new
with the edge index edge_index
in the backwards adjacency list. Also perform the same operations on the forward adjacency lists fadjlist1
and fadjlist2
.
Examples
julia> g=JosephsonCircuits.Graphs.SimpleDiGraphFromIterator(JosephsonCircuits.tuple2edge([(1,1),(2,1),(2,3)]));JosephsonCircuits.move_bedge!(g,1,2,1,deepcopy(g.fadjlist),deepcopy(g.fadjlist));g.badjlist
3-element Vector{Vector{Int64}}:
[2]
[1]
[2]
JosephsonCircuits.move_bedges!
— Methodmove_bedges!(g,dst_node,dst_node_new,fadjlist1,fadjlist2)
Move the edges from graph g
at destination node dst_node
to the new destination node dst_node_new
in the backwards adjacency list. Also perform the same operations on the forward adjacency lists fadjlist1
and fadjlist2
.
Examples
julia> g=JosephsonCircuits.Graphs.SimpleDiGraphFromIterator(JosephsonCircuits.tuple2edge([(1,1),(2,1),(2,3)]));JosephsonCircuits.move_bedges!(g,1,2,deepcopy(g.fadjlist),deepcopy(g.fadjlist));g.badjlist
3-element Vector{Vector{Int64}}:
[]
[2, 1]
[2]
JosephsonCircuits.move_edges!
— Methodmove_edges!(g,node,node_new,fadjlist1,fadjlist2)
Move the edges from graph g
at node node
to the new node node_new
. Also perform the same operations on the forward adjacency lists fadjlist1
and fadjlist2
.
Examples
julia> g=JosephsonCircuits.Graphs.SimpleDiGraphFromIterator(JosephsonCircuits.tuple2edge([(1,1),(2,1),(2,3)]));JosephsonCircuits.move_edges!(g,1,2,deepcopy(g.fadjlist),deepcopy(g.fadjlist));g.fadjlist
3-element Vector{Vector{Int64}}:
[]
[3, 2, 2]
[]
JosephsonCircuits.move_fedge!
— Methodmove_fedge!(g,src_node,src_node_new,edge_index,fadjlist1,fadjlist2)
Move an edge from graph g
at source node src_node
to the new source node src_node_new
with the edge index edge_index
in the forward adjacency list. Also perform the same operations on the forward adjacency lists fadjlist1
and fadjlist2
.
Examples
julia> g=JosephsonCircuits.Graphs.SimpleDiGraphFromIterator(JosephsonCircuits.tuple2edge([(1,1),(2,1),(2,3)]));JosephsonCircuits.move_fedge!(g,1,2,1,deepcopy(g.fadjlist),deepcopy(g.fadjlist));g.fadjlist
3-element Vector{Vector{Int64}}:
[]
[1, 3, 1]
[]
JosephsonCircuits.move_fedges!
— Methodmove_fedges!(g,src_node,src_node_new,fadjlist1,fadjlist2)
Move the edges from graph g
at source node src_node
to the new source node src_node_new
in the forward adjacency list. Also perform the same operations on the forward adjacency lists fadjlist1
and fadjlist2
.
Examples
julia> g=JosephsonCircuits.Graphs.SimpleDiGraphFromIterator(JosephsonCircuits.tuple2edge([(1,1),(2,1),(2,3)]));JosephsonCircuits.move_fedges!(g,1,2,deepcopy(g.fadjlist),deepcopy(g.fadjlist));g.fadjlist
3-element Vector{Vector{Int64}}:
[]
[1, 3, 1]
[]
JosephsonCircuits.mutual_to_even_odd
— Methodmutual_to_even_odd(L, Cmutual)
Return the even and odd mode impedances and the even and odd mode indices from the inductance matrix L
and the mutual capacitance matrix Cmutual
.
Examples
@variables Cg, Cm, Ls, Lm
C = [Cg Cm; Cm Cg]
L = [Ls Lm; Lm Ls]
Zeven, Zodd, neven, nodd = JosephsonCircuits.mutual_to_even_odd(L,C)
@show Zeven
@show Zodd
@show neven
@show nodd
;
# output
Zeven = sqrt((Lm + Ls) / Cg)
Zodd = sqrt((-Lm + Ls) / (Cg + 2Cm))
neven = 2.99792458e8sqrt(Cg*(Lm + Ls))
nodd = 2.99792458e8sqrt((Cg + 2Cm)*(-Lm + Ls))
JosephsonCircuits.mutual_to_maxwell
— Methodmaxwell_to_mutual(Cmutual::AbstractMatrix)
Return the Maxwell capacitance matrix from the mutual capacitance matrix Cmutual
.
The Maxwell capacitance Cmaxwell
is the relationship between charge and voltage on each node, Q = C V or dQi/dVj = C_ij where C
is the Maxwell capacitance matrix.
Each element of the mutual capacitance matrix Cmutual
is the value of a physical capacitor placed between two nodes in a circuit or between a node and ground.
Examples
julia> @variables Cg, Cm;C = [Cg Cm;Cm Cg];JosephsonCircuits.mutual_to_maxwell(C)
2×2 Matrix{Num}:
Cg + Cm -Cm
-Cm Cg + Cm
julia> C = [0.9 0.1;0.1 1.9];JosephsonCircuits.mutual_to_maxwell(C)
2×2 Matrix{Float64}:
1.0 -0.1
-0.1 2.0
JosephsonCircuits.networkdatatoarray
— Methodnetworkdatatoarray(networkdata, numberofports, numberoffrequencies,
matrixformat, twoportdataorder, parameter, frequencyunit, format, R,
version)
Examples
networkdata = [4.0, 0.9995813511383583, -17.248815971093425, 4.5, 0.9958480363660398, -26.451285931791276, 5.0, 0.9868361175866559, 2.711906450972103, 5.5, 0.9985678550072272, -12.21545548845392, 6.0, 0.9993761539770525, -16.045248853866596]
numberofports = 1
numberoffrequencies = 5
matrixformat = "Full"
twoportdataorder = "12_21"
parameter = "s"
frequencyunit = "ghz"
format = "ma"
R = 50.0
version = 2.0
frequencies, N = JosephsonCircuits.networkdatatoarray(networkdata,
numberofports, numberoffrequencies, matrixformat, twoportdataorder,
parameter, frequencyunit, format, R, version)
println(frequencies)
println(N[1,1,:])
# output
[4.0e9, 4.5e9, 5.0e9, 5.5e9, 6.0e9]
ComplexF64[0.9546262517670427 - 0.296397700700921im, 0.8915960960938982 - 0.44358732281729774im, 0.9857309246425359 + 0.04669118949947016im, 0.9759591344506418 - 0.21128542054786678im, 0.9604441706426364 - 0.2762239892126382im]
JosephsonCircuits.nlsolve!
— Methodnlsolve!(fj!, F, J::SparseMatrixCSC, x; iterations=1000, ftol=1e-8,
switchofflinesearchtol = 1e-5)
A simple nonlinear solver for sparse matrices using Newton's method with linesearch based on Nocedal and Wright, chapter 3 section 5.
This solver attempts to find x such that f(x) == 0, where f is a nonlinear function with Jacobian J.
A few points to note: (1) It uses KLU factorization, so only works on sparse matrices. (2) The Jacobian J cannot change sparsity structure. (3) This function attempts to reuse the symbolic factorization which can sometimes result in a SingularException, which we catch, then create a new factorization object.
Arguments
fj!
: a function to compute a vector-valued objective function and
its Jacobian.
F
: matrix for holding intermediate results. Initial values may be overwritten and can be bogus values.J
: sparse matrix with with the desired sparsity structure of the Jacobian. Initial values may be overwritten and can be bogus values, as long as the sparsity structure is correct.x
: initial guess for x.
Examples
function fj!(F, J, x)
if !isnothing(F)
F[1] = (x[1]+3)*(x[2]^3-7)+18
F[2] = sin(x[2]*exp(x[1])-1)
end
if !isnothing(J)
J[1, 1] = x[2]^3-7
J[1, 2] = 3*x[2]^2*(x[1]+3)
u = exp(x[1])*cos(x[2]*exp(x[1])-1)
J[2, 1] = x[2]*u
J[2, 2] = u
end
return nothing
end
x = [ 0.1, 1.2]
F = [0.0, 0.0]
J = JosephsonCircuits.sparse([1, 1, 2, 2],[1, 2, 1, 2],[1.3, 0.5, 0.1, 1.2])
JosephsonCircuits.nlsolve!(fj!, F, J, x)
isapprox([0.0,1.0],x)
# output
true
JosephsonCircuits.nodevariabletokeyed
— Methodnodevariabletokeyed(nodevariable, outputmodes, nodenames, inputmodes,
inputportnumbers, w)
Convert a node variable array nodevariable
(such as node flux or node voltage) vs frequency w
to a keyed array. Return the keyed array.
Examples
julia> JosephsonCircuits.nodevariabletokeyed([1 2;3 4;;;],[(0,),(1,)],["0","1"],[(0,),(1,)],[1],[1.0])
5-dimensional KeyedArray(NamedDimsArray(...)) with keys:
↓ outputmode ∈ 2-element Vector{Tuple{Int64}}
→ node ∈ 1-element Vector{String}
◪ inputmode ∈ 2-element Vector{Tuple{Int64}}
▨ inputport ∈ 1-element Vector{Int64}
▨ freqindex ∈ 1-element UnitRange{Int64}
And data, 2×1×2×1×1 Array{Int64, 5}:
[:, :, 1, 1, 1] ~ (:, :, (0,), 1, 1):
("1")
(0,) 1
(1,) 3
[:, :, 2, 1, 1] ~ (:, :, (1,), 1, 1):
("1")
(0,) 2
(1,) 4
JosephsonCircuits.nodevariabletokeyed
— Methodnodevariabletokeyed(nodevariable, outputmodes, nodenames)
Convert a node variable array nodevariable
(such as node flux or node voltage) to a keyed array. Return the keyed array.
Examples
julia> JosephsonCircuits.nodevariabletokeyed([1 2;3 4],[(0,),(1,)],["0","1","2"])
2-dimensional KeyedArray(NamedDimsArray(...)) with keys:
↓ outputmode ∈ 2-element Vector{Tuple{Int64}}
→ node ∈ 2-element Vector{String}
And data, 2×2 Matrix{Int64}:
("1") ("2")
(0,) 1 2
(1,) 3 4
JosephsonCircuits.numericmatrices
— Methodnumericmatrices(circuit, circuitdefs; Nmodes = 1, sorting = :number)
Return the numeric matrices describing the circuit properties.
See also CircuitMatrices
, numericmatrices
, calcCn
, calcGn
, calcLb
,calcLjb
, calcMb
, calcinvLn
, calcLmean
, calcportindicesnumbers
, calcportimpedanceindices
, and calcnoiseportimpedanceindices
.
Examples
@variables Ipump Rleft Cc Lj Cj
circuit = Vector{Tuple{String,String,String,Num}}(undef,0)
push!(circuit,("P1","1","0",1))
push!(circuit,("I1","1","0",Ipump))
push!(circuit,("R1","1","0",Rleft))
push!(circuit,("C1","1","2",Cc))
push!(circuit,("Lj1","2","0",Lj))
push!(circuit,("C2","2","0",Cj))
circuitdefs = Dict(Lj =>1000.0e-12,Cc => 100.0e-15,Cj => 1000.0e-15,Rleft => 50.0,Ipump => 1.0e-8)
JosephsonCircuits.testshow(stdout,numericmatrices(circuit,circuitdefs))
# output
JosephsonCircuits.CircuitMatrices(sparse([1, 2, 1, 2], [1, 1, 2, 2], [1.0e-13, -1.0e-13, -1.0e-13, 1.1e-12], 2, 2), sparse([1], [1], [0.02], 2, 2), sparsevec(Int64[], Nothing[], 2), sparsevec(Int64[], Nothing[], 2), sparsevec([2], [1.0e-9], 2), sparsevec([2], [1.0e-9], 2), sparse(Int64[], Int64[], Nothing[], 2, 2), sparse(Int64[], Int64[], Nothing[], 2, 2), sparse([1, 2], [1, 2], [1, 1], 2, 2), [1], [1], [3], Int64[], 1.0e-9, Real[1, 1.0e-8, 50.0, 1.0e-13, 1.0e-9, 1.0e-12])
@variables Ipump Rleft Cc Lj Cj
circuit = Vector{Tuple{String,String,String,Num}}(undef,0)
push!(circuit,("P1","1","0",1))
push!(circuit,("I1","1","0",Ipump))
push!(circuit,("R1","1","0",Rleft))
push!(circuit,("C1","1","2",Cc))
push!(circuit,("Lj1","2","0",Lj))
push!(circuit,("C2","2","0",Cj))
circuitdefs = Dict(Lj =>1000.0e-12,Cc => 100.0e-15,Cj => 1000.0e-15,Rleft => 50.0,Ipump => 1.0e-8)
psc = JosephsonCircuits.parsesortcircuit(circuit)
cg = JosephsonCircuits.calccircuitgraph(psc)
JosephsonCircuits.testshow(stdout,numericmatrices(psc, cg, circuitdefs))
# output
JosephsonCircuits.CircuitMatrices(sparse([1, 2, 1, 2], [1, 1, 2, 2], [1.0e-13, -1.0e-13, -1.0e-13, 1.1e-12], 2, 2), sparse([1], [1], [0.02], 2, 2), sparsevec(Int64[], Nothing[], 2), sparsevec(Int64[], Nothing[], 2), sparsevec([2], [1.0e-9], 2), sparsevec([2], [1.0e-9], 2), sparse(Int64[], Int64[], Nothing[], 2, 2), sparse(Int64[], Int64[], Nothing[], 2, 2), sparse([1, 2], [1, 2], [1, 1], 2, 2), [1], [1], [3], Int64[], 1.0e-9, Real[1, 1.0e-8, 50.0, 1.0e-13, 1.0e-9, 1.0e-12])
JosephsonCircuits.parse_connections_sparse
— Methodparse_connections_sparse(networks::AbstractVector{Tuple{T,N}},
connections::AbstractVector{Tuple{T,T,Int,Int}}) where {T,N}
Return the indices of the internal ports portc_indices
, the external ports portp_indices
, the vector of port tuples ports
, the vector of scattering parameter data networkdata
, the connection matrix gamma
, the sparse matrix containing indices in networkdata Sindices
, and an empty sparse matrix of scattering parameter data S
. The scattering parameter data consists of the input networks assembled as a block diagonal matrix.
References
V. A. Monaco and P. Tiberio, "Computer-Aided Analysis of Microwave Circuits," in IEEE Transactions on Microwave Theory and Techniques, vol. 22, no. 3, pp. 249-263, Mar. 1974, doi: 10.1109/TMTT.1974.1128208.
JosephsonCircuits.parsecircuit
— Methodparsecircuit(circuit)
Parse circuit
which is a vector where each element contains a tuple with the component name, the first node, the second node, and the component value. Component values can be numbers, symbols, or symbolic variables (including symbolic functions).
The nodes can be arbitrary strings for SPICE compatibility. Integers are also supported but are converted internally to strings. The ground node is "0" and is required. Specifying the type of the vector circuit
is optional; although, typically a vector with a type union is preferable to an array of type Any.
Arguments
circuit
: vector of tuples each of which contain the component name, the first node, the second node, and the component value.
Examples
@variables Ipump Rleft L1 K1 L2 C2
circuit = Vector{Tuple{String,String,String,Num}}(undef,0)
push!(circuit,("P1","1","0",1))
push!(circuit,("I1","1","0",Ipump))
push!(circuit,("R1","1","0",Rleft))
push!(circuit,("L1","1","0",L1))
push!(circuit,("K1","L1","L2",K1))
push!(circuit,("L2","2","0",L2))
push!(circuit,("C2","2","0",C2))
parsecircuit(circuit)
# output
JosephsonCircuits.ParsedCircuit([1, 2, 1, 2, 1, 2, 1, 2, 0, 0, 3, 2, 3, 2], ["1", "0", "2"], ["L1", "L2"], ["P1", "I1", "R1", "L1", "K1", "L2", "C2"], [:P, :I, :R, :L, :K, :L, :C], Num[1, Ipump, Rleft, L1, K1, L2, C2], Dict("L1" => 4, "I1" => 2, "L2" => 6, "C2" => 7, "R1" => 3, "P1" => 1, "K1" => 5), 3)
@variables Ipump Rleft L1 L2 C2
Kfun(L) = sin(L);@register_symbolic Kfun(L1)
circuit = Vector{Tuple{String,String,String,Num}}(undef,0)
push!(circuit,("P1","1","0",1))
push!(circuit,("I1","1","0",Ipump))
push!(circuit,("R1","1","0",Rleft))
push!(circuit,("L1","1","0",L1))
push!(circuit,("K1","L1","L2",Kfun(L1)))
push!(circuit,("L2","2","0",L2))
push!(circuit,("C2","2","0",C2))
parsecircuit(circuit)
# output
JosephsonCircuits.ParsedCircuit([1, 2, 1, 2, 1, 2, 1, 2, 0, 0, 3, 2, 3, 2], ["1", "0", "2"], ["L1", "L2"], ["P1", "I1", "R1", "L1", "K1", "L2", "C2"], [:P, :I, :R, :L, :K, :L, :C], Num[1, Ipump, Rleft, L1, Kfun(L1), L2, C2], Dict("L1" => 4, "I1" => 2, "L2" => 6, "C2" => 7, "R1" => 3, "P1" => 1, "K1" => 5), 3)
circuit = Vector{Tuple{String,String,String,Union{Complex{Float64}, Symbol,Int}}}(undef,0)
push!(circuit,("P1","1","0",1))
push!(circuit,("I1","1","0",:Ipump))
push!(circuit,("R1","1","0",:Rleft))
push!(circuit,("C1","1","2",:Cc))
push!(circuit,("Lj1","2","0",:Lj))
push!(circuit,("C2","2","0",:Cj))
parsecircuit(circuit)
# output
JosephsonCircuits.ParsedCircuit([1, 2, 1, 2, 1, 2, 1, 3, 3, 2, 3, 2], ["1", "0", "2"], String[], ["P1", "I1", "R1", "C1", "Lj1", "C2"], [:P, :I, :R, :C, :Lj, :C], Union{Int64, Symbol, ComplexF64}[1, :Ipump, :Rleft, :Cc, :Lj, :Cj], Dict("I1" => 2, "C1" => 4, "C2" => 6, "R1" => 3, "P1" => 1, "Lj1" => 5), 3)
circuit = Vector{Tuple{String,String,String,Union{Complex{Float64}, Symbol,Int}}}(undef,0)
push!(circuit,("P1","One","0",1))
push!(circuit,("I1","One","0",:Ipump))
push!(circuit,("R1","One","0",:Rleft))
push!(circuit,("C1","One","Two",:Cc))
push!(circuit,("Lj1","Two","0",:Lj))
push!(circuit,("C2","Two","0",:Cj))
parsecircuit(circuit)
# output
JosephsonCircuits.ParsedCircuit([1, 2, 1, 2, 1, 2, 1, 3, 3, 2, 3, 2], ["One", "0", "Two"], String[], ["P1", "I1", "R1", "C1", "Lj1", "C2"], [:P, :I, :R, :C, :Lj, :C], Union{Int64, Symbol, ComplexF64}[1, :Ipump, :Rleft, :Cc, :Lj, :Cj], Dict("I1" => 2, "C1" => 4, "C2" => 6, "R1" => 3, "P1" => 1, "Lj1" => 5), 3)
circuit = []
push!(circuit,("P1","1","0",1))
push!(circuit,("I1","1","0",:Ipump))
push!(circuit,("R1","1","0",:Rleft))
push!(circuit,("C1","1","2",:Cc))
push!(circuit,("Lj1","2","0",:Lj))
push!(circuit,("C2","2","0",:Cj))
parsecircuit(circuit)
# output
JosephsonCircuits.ParsedCircuit([1, 2, 1, 2, 1, 2, 1, 3, 3, 2, 3, 2], ["1", "0", "2"], String[], ["P1", "I1", "R1", "C1", "Lj1", "C2"], [:P, :I, :R, :C, :Lj, :C], Any[1, :Ipump, :Rleft, :Cc, :Lj, :Cj], Dict("I1" => 2, "C1" => 4, "C2" => 6, "R1" => 3, "P1" => 1, "Lj1" => 5), 3)
circuit = Vector{Tuple{String,String,String,Union{Complex{Float64}, Symbol,Int}}}(undef,0)
push!(circuit,("P1","1","0",1))
push!(circuit,("I1","1","0",:Ipump))
push!(circuit,("R1","1","0",:Rleft))
push!(circuit,("L1","1","0",:L1))
push!(circuit,("K1","L1","L2",:K1))
push!(circuit,("L2","2","0",:L2))
push!(circuit,("C2","2","0",:C2))
parsecircuit(circuit)
# output
JosephsonCircuits.ParsedCircuit([1, 2, 1, 2, 1, 2, 1, 2, 0, 0, 3, 2, 3, 2], ["1", "0", "2"], ["L1", "L2"], ["P1", "I1", "R1", "L1", "K1", "L2", "C2"], [:P, :I, :R, :L, :K, :L, :C], Union{Int64, Symbol, ComplexF64}[1, :Ipump, :Rleft, :L1, :K1, :L2, :C2], Dict("L1" => 4, "I1" => 2, "L2" => 6, "C2" => 7, "R1" => 3, "P1" => 1, "K1" => 5), 3)
JosephsonCircuits.parsecomponenttype
— Methodparsecomponenttype(name::String,allowedcomponents::Vector{String})
The first one or two characters of the component name in the string name
should match one of the strings in the vector allowedcomponents
. Return the index first of the match found.
NOTE: if a two letter component appears in allowedcomponents after a one letter component with the same starting letter this function will match on the first value.
Examples
julia> JosephsonCircuits.parsecomponenttype("L10",["Lj","L","C","K","I","R","P"])
2
julia> [JosephsonCircuits.parsecomponenttype(c,["Lj","L","C","K","I","R","P"]) for c in ["Lj","L","C","K","I","R","P"]]
7-element Vector{Int64}:
1
2
3
4
5
6
7
julia> JosephsonCircuits.parsecomponenttype("L10",["Lj","L","C","K","I","R","P"])
2
JosephsonCircuits.parseinformation!
— Methodparseinformation!(information::Vector{String},io::IO)
Append the contents of the information section of a Touchstone file from the IOBuffer or IOStream io
to the vector information
.
Examples
information = String[]
comments = String[]
io = IOBuffer("This is an information section.
[End Information]")
JosephsonCircuits.parseinformation!(information,comments,io)
println(information)
# output
["this is an information section."]
JosephsonCircuits.parsematrixformat
— Methodparsematrixformat(line::String)
Return the two-port data order string parsed from the [two-port data order] line of a Touchstone file.
Examples
julia> JosephsonCircuits.parsematrixformat("[matrix format] lower")
"Lower"
julia> JosephsonCircuits.parsematrixformat("[matrix format] upper")
"Upper"
JosephsonCircuits.parsemixedmodeorder!
— Methodparsemixedmodeorder!(mixedmodeorder::Vector{Tuple{Char, Vector{Int}}},
line::String)
Append the contents of the [mixed-mode order] line of a Touchstone file from the to the vector mixedmodeorder
.
Examples
julia> mixedmodeorder = Tuple{Char, Vector{Int}}[];JosephsonCircuits.parsemixedmodeorder!(mixedmodeorder,"[Mixed-Mode Order] D2,3 D6,5 C2,3 C6,5 S4 S1");mixedmodeorder
6-element Vector{Tuple{Char, Vector{Int64}}}:
('D', [2, 3])
('D', [6, 5])
('C', [2, 3])
('C', [6, 5])
('S', [4])
('S', [1])
JosephsonCircuits.parsenetworkdata!
— Methodparsenetworkdata!(networkdata::Vector{Float64}, comments::Vector{String}, io::IO)
Append the contents of the networkdata section of a Touchstone file from the IOBuffer or IOStream io
to the vector networkdata
.
Examples
networkdata = Float64[]
comments = String[]
io = IOBuffer("1.0000 0.3926 -0.1211 -0.0003 -0.0021 -0.0003 -0.0021 0.3926 -0.1211
2.0000 0.3517 -0.3054 -0.0096 -0.0298 -0.0096 -0.0298 0.3517 -0.3054
10.000 0.3419 0.3336 -0.0134 0.0379 -0.0134 0.0379 0.3419 0.3336")
JosephsonCircuits.parsenetworkdata!(networkdata,comments,io)
println(networkdata)
# output
[1.0, 0.3926, -0.1211, -0.0003, -0.0021, -0.0003, -0.0021, 0.3926, -0.1211, 2.0, 0.3517, -0.3054, -0.0096, -0.0298, -0.0096, -0.0298, 0.3517, -0.3054, 10.0, 0.3419, 0.3336, -0.0134, 0.0379, -0.0134, 0.0379, 0.3419, 0.3336]
networkdata = Float64[]
comments = String[]
io = IOBuffer("2 .95 -26 3.57 157 .04 76 .66 -14
22 .60 -144 1.30 40 .14 40 .56 -85
! NOISE PARAMETERS
4 .7 .64 69 .38
18 2.7 .46 -33 .40")
JosephsonCircuits.parsenetworkdata!(networkdata,comments,io)
println(networkdata)
# output
[2.0, 0.95, -26.0, 3.57, 157.0, 0.04, 76.0, 0.66, -14.0, 22.0, 0.6, -144.0, 1.3, 40.0, 0.14, 40.0, 0.56, -85.0]
networkdata = Float64[]
comments = String[]
io = IOBuffer("2 .95 -26 3.57 157 .04 76 .66 -14
22 .60 -144 1.30 40 .14 40 .56 -85
[Noise Data]
4 .7 .64 69 19
18 2.7 .46 -33 20
[End]")
JosephsonCircuits.parsenetworkdata!(networkdata,comments,io)
println(networkdata)
# output
[2.0, 0.95, -26.0, 3.57, 157.0, 0.04, 76.0, 0.66, -14.0, 22.0, 0.6, -144.0, 1.3, 40.0, 0.14, 40.0, 0.56, -85.0]
JosephsonCircuits.parsenoisedata!
— Methodparsenoisedata!(noisedata::Vector{Float64}, comments::Vector{String},
io::IO)
Append the contents of the networkdata section of a Touchstone file from the IOBuffer or IOStream io
to the vector networkdata
.
Examples
networkdata = Float64[]
noisedata = Float64[]
comments = String[]
io = IOBuffer("1.0000 0.3926 -0.1211 -0.0003 -0.0021 -0.0003 -0.0021 0.3926 -0.1211
2.0000 0.3517 -0.3054 -0.0096 -0.0298 -0.0096 -0.0298 0.3517 -0.3054
10.000 0.3419 0.3336 -0.0134 0.0379 -0.0134 0.0379 0.3419 0.3336")
JosephsonCircuits.parsenetworkdata!(networkdata,comments,io)
JosephsonCircuits.parsenoisedata!(noisedata,comments,io)
println(noisedata)
# output
Float64[]
networkdata = Float64[]
noisedata = Float64[]
comments = String[]
io = IOBuffer("2 .95 -26 3.57 157 .04 76 .66 -14
22 .60 -144 1.30 40 .14 40 .56 -85
! NOISE PARAMETERS
4 .7 .64 69 .38
18 2.7 .46 -33 .40")
JosephsonCircuits.parsenetworkdata!(networkdata,comments,io)
JosephsonCircuits.parsenoisedata!(noisedata,comments,io)
println(noisedata)
# output
[4.0, 0.7, 0.64, 69.0, 0.38, 18.0, 2.7, 0.46, -33.0, 0.4]
networkdata = Float64[]
noisedata = Float64[]
comments = String[]
io = IOBuffer("2 .95 -26 3.57 157 .04 76 .66 -14
22 .60 -144 1.30 40 .14 40 .56 -85
[Noise Data]
4 .7 .64 69 19
18 2.7 .46 -33 20
[End]")
JosephsonCircuits.parsenetworkdata!(networkdata,comments,io)
JosephsonCircuits.parsenoisedata!(noisedata,comments,io)
println(noisedata)
# output
[4.0, 0.7, 0.64, 69.0, 19.0, 18.0, 2.7, 0.46, -33.0, 20.0]
JosephsonCircuits.parsenumberoffrequencies
— Methodparsenumberoffrequencies(line::String)
Return the number of frequencies parsed from the [number of frequencies] line of a Touchstone file.
Examples
julia> JosephsonCircuits.parsenumberoffrequencies("[number of frequencies] 10")
10
JosephsonCircuits.parsenumberofnoisefrequencies
— Methodparsenumberofnoisefrequencies(line::String)
Return the number of noise frequencies parsed from the [number of noise frequencies] line of a Touchstone file.
Examples
julia> JosephsonCircuits.parsenumberofnoisefrequencies("[number of noise frequencies] 10")
10
JosephsonCircuits.parsenumberofports
— Methodparsenumberofports(line::String)
Return the number of ports parsed from the [number of ports] line of a Touchstone file.
Examples
julia> JosephsonCircuits.parsenumberofports("[number of ports] 1")
1
JosephsonCircuits.parseoptionline
— Methodparseoptionline(line::String)
Return a struct TouchstoneOptionLine which contains the option line of a Touchstone file.
Examples
julia> JosephsonCircuits.parseoptionline("# MHz Z MA R 75")
JosephsonCircuits.TouchstoneOptionLine("MHz", "Z", "MA", 75.0)
julia> JosephsonCircuits.parseoptionline("# MHz H RI R 75")
JosephsonCircuits.TouchstoneOptionLine("MHz", "H", "RI", 75.0)
JosephsonCircuits.parsereference!
— Methodparsereference!(reference::Vector{Float64}, comments::Vector{String},
line::String, numberofports::Int, io::IO)
Append the contents of the [reference] section of a Touchstone file from the IOBuffer or IOStream io
to the vector reference
. The reference impedance values can be spread across multiple lines.
Examples
io = IOBuffer("[Reference] 50.0 60.0 75.0")
numberofports = 3
comments = String[]
reference = Float64[]
line = JosephsonCircuits.stripcommentslowercase!(comments,readline(io))
JosephsonCircuits.parsereference!(reference, comments, line, numberofports, io)
println(reference)
# output
[50.0, 60.0, 75.0]
io = IOBuffer("[Reference] 50.0
60.0 75.0")
numberofports = 3
comments = String[]
reference = Float64[]
line = JosephsonCircuits.stripcommentslowercase!(comments,readline(io))
JosephsonCircuits.parsereference!(reference, comments, line, numberofports, io)
println(reference)
# output
[50.0, 60.0, 75.0]
io = IOBuffer("[Reference] 50.0
60.0 75.0
[Number of Frequencies] 1")
numberofports = 3
comments = String[]
reference = Float64[]
line = JosephsonCircuits.stripcommentslowercase!(comments,readline(io))
JosephsonCircuits.parsereference!(reference, comments, line, numberofports, io)
println(reference)
# output
[50.0, 60.0, 75.0]
JosephsonCircuits.parsesortcircuit
— Methodparsesortcircuit(circuit; sorting = :name)
Parse and sort the circuit. See parsecircuit
, sortnodes
for more explanation.
Arguments
circuit
: vector of tuples each of which contain the component name, the first node, the second node, and the component value. The first three must be strings.
Keywords
sorting = :name
: Sort the vector of strings. This always works but leads to results like "101" comes before "11".sorting = :number
: Convert the node strings to integer and sort by these (this errors if the nodes names cannot be converted to integers).sorting = :none
: Don't perform any sorting except to place the ground node first. In other words, order the nodes in the order they are found incircuit
.
Examples
@variables Ipump Rleft Cc Lj Cj
circuit = Tuple{String,String,String,Num}[]
push!(circuit,("P1","1","0",1))
push!(circuit,("I1","1","0",Ipump))
push!(circuit,("R1","1","0",Rleft))
push!(circuit,("C1","1","2",Cc))
push!(circuit,("Lj1","2","0",Lj))
push!(circuit,("C2","2","0",Cj))
println(parsesortcircuit(circuit))
# output
JosephsonCircuits.ParsedSortedCircuit([2 2 2 2 3 3; 1 1 1 3 1 1], ["0", "1", "2"], String[], ["P1", "I1", "R1", "C1", "Lj1", "C2"], [:P, :I, :R, :C, :Lj, :C], Num[1, Ipump, Rleft, Cc, Lj, Cj], Dict("I1" => 2, "C1" => 4, "C2" => 6, "R1" => 3, "P1" => 1, "Lj1" => 5), 3)
@variables Ipump Rleft L1 L2 C2
Kfun(L) = sin(L);@register_symbolic Kfun(L1)
circuit = Tuple{String,String,String,Num}[]
push!(circuit,("P1","1","0",1))
push!(circuit,("I1","1","0",Ipump))
push!(circuit,("R1","1","0",Rleft))
push!(circuit,("L1","1","0",L1))
push!(circuit,("K1","L1","L2",Kfun(L1)))
push!(circuit,("L2","2","0",L2))
push!(circuit,("C2","2","0",C2))
println(parsesortcircuit(circuit))
# output
JosephsonCircuits.ParsedSortedCircuit([2 2 2 2 0 3 3; 1 1 1 1 0 1 1], ["0", "1", "2"], ["L1", "L2"], ["P1", "I1", "R1", "L1", "K1", "L2", "C2"], [:P, :I, :R, :L, :K, :L, :C], Num[1, Ipump, Rleft, L1, Kfun(L1), L2, C2], Dict("L1" => 4, "I1" => 2, "L2" => 6, "C2" => 7, "R1" => 3, "P1" => 1, "K1" => 5), 3)
JosephsonCircuits.parsespicevariable
— Methodparsespicevariable(variable::String)
Parse a variable name string into the variable name and node number. Will this work with arbitrary node strings?
Examples
julia> JosephsonCircuits.parsespicevariable("V1(5)")
("V1", 5)
julia> JosephsonCircuits.parsespicevariable("V1")
("V", 1)
julia> JosephsonCircuits.parsespicevariable("V-1")
("V", 1)
julia> JosephsonCircuits.parsespicevariable("frequency")
("frequency", "frequency")
JosephsonCircuits.parsetwoportdataorder
— Methodparsetwoportdataorder(line::String)
Return the two-port data order string parsed from the [two-port data order] line of a Touchstone file.
Examples
julia> JosephsonCircuits.parsetwoportdataorder("[two-port data order] 12_21")
"12_21"
julia> JosephsonCircuits.parsetwoportdataorder("[two-port data order] 21_12")
"21_12"
JosephsonCircuits.parseversion
— Methodparseversion(line::String)
Return the version parsed from the [version] line of a Touchstone file.
Examples
julia> JosephsonCircuits.parseversion("[version] 1.0")
1.0
JosephsonCircuits.phimatrixtovector!
— Methodphimatrixtovector!(phivector::Vector, phimatrix::Array,
indexmap::Vector{Int}, conjsourceindices::Vector{Int},
conjtargetindices::Vector{Int}, Nbranches::Int)
The harmonic balance method requires a vector with all of the conjugate symmetric terms removed and potentially other terms dropped if specified by the user ( for example, intermodulation products which are not of interest) whereas the Fourier transform operates on multidimensional arrays with the proper conjugate symmetries and with dropped terms set to zero. This function converts an array to a vector with the above properties.
Examples
freqindexmap = [2, 4, 6, 8, 12, 16, 27, 33]
conjsourceindices = [16, 6]
conjtargetindices = [21, 31]
Nbranches = 1
phivector = zeros(Complex{Float64}, Nbranches*length(freqindexmap))
phimatrix = [0.0 + 0.0im 0.0 + 3.0im 0.0 + 0.0im 0.0 + 6.0im 0.0 - 6.0im 0.0 + 0.0im 0.0 - 3.0im; 0.0 + 1.0im 0.0 + 0.0im 0.0 + 5.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 7.0im 0.0 + 0.0im; 0.0 + 0.0im 0.0 + 4.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 8.0im; 0.0 + 2.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im; 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im;;;]
JosephsonCircuits.phimatrixtovector!(phivector,
phimatrix,
freqindexmap,
conjsourceindices,
conjtargetindices,
Nbranches,
)
phivector
# output
8-element Vector{ComplexF64}:
0.0 + 1.0im
0.0 + 2.0im
0.0 + 3.0im
0.0 + 4.0im
0.0 + 5.0im
0.0 + 6.0im
0.0 + 7.0im
0.0 + 8.0im
JosephsonCircuits.phivectortomatrix!
— Methodphivectortomatrix!(phivector::AbstractVector,phimatrix::AbstractArray,
indexmap::Vector{Int},conjsourceindices::Vector{Int},
conjtargetindices::Vector{Int},Nbranches::Int)
The harmonic balance method requires a vector with all of the conjugate symmetric terms removed and potentially other terms dropped if specified by the user ( for example, intermodulation products which are not of interest) whereas the Fourier transform operates on multidimensional arrays with the proper conjugate symmetries and with dropped terms set to zero. This function converts a vector to an array with the above properties.
Examples
freqindexmap = [2, 4, 6, 8, 12, 16, 27, 33]
conjsourceindices = [16, 6]
conjtargetindices = [21, 31]
Nbranches = 1
phivector = 1im.*Complex.(1:Nbranches*length(freqindexmap));
phimatrix=zeros(Complex{Float64},5,7,1)
JosephsonCircuits.phivectortomatrix!(phivector,
phimatrix,
freqindexmap,
conjsourceindices,
conjtargetindices,
Nbranches,
)
phimatrix
# output
5×7×1 Array{ComplexF64, 3}:
[:, :, 1] =
0.0+0.0im 0.0+3.0im 0.0+0.0im 0.0+6.0im 0.0-6.0im 0.0+0.0im 0.0-3.0im
0.0+1.0im 0.0+0.0im 0.0+5.0im 0.0+0.0im 0.0+0.0im 0.0+7.0im 0.0+0.0im
0.0+0.0im 0.0+4.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+8.0im
0.0+2.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im
0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im
JosephsonCircuits.pivot_rows
— Methodpivot_rows(A11,A21)
Return true if pivoting during LU decomposition.
Examples
julia> @variables A21;JosephsonCircuits.pivot_rows(0,A21)
true
julia> @variables A11 A21;JosephsonCircuits.pivot_rows(A11,A21)
false
JosephsonCircuits.pivot_rows
— Methodpivot_rows(A11::Union{T,Complex{T}},
A21::Union{T,Complex{T}}) where {T<:AbstractFloat}
Return true if pivoting during LU decomposition.
Examples
julia> JosephsonCircuits.pivot_rows(0.1+0.0im,0.9+0.1im)
true
julia> JosephsonCircuits.pivot_rows(0.9+0.1im,0.1+0.0im)
false
JosephsonCircuits.plan_applynl
— Methodplan_applynl(fd::Array{Complex{T}})
Creates an empty time domain data array and the inverse and forward plans for the RFFT of an array of frequency domain data. See also applynl!
.
JosephsonCircuits.printsymmetries
— Methodprintsymmetries(freq::Frequencies)
See printsymmetries
.
Examples
julia> JosephsonCircuits.printsymmetries(JosephsonCircuits.calcfreqsrdft((2,)))
3-element Vector{Int64}:
0
0
0
julia> JosephsonCircuits.printsymmetries(JosephsonCircuits.calcfreqsdft((2,)))
5-element Vector{Int64}:
0
1
2
-2
-1
julia> JosephsonCircuits.printsymmetries(JosephsonCircuits.calcfreqsrdft((2,2)))
3×5 Matrix{Int64}:
0 1 3 -3 -1
0 0 0 0 0
0 2 4 -4 -2
JosephsonCircuits.printsymmetries
— Methodprintsymmetries(Nw::NTuple{N, Int}, Nt::NTuple{N, Int})
Print the conjugate symmetries in the multi-dimensional DFT or RDFT from the dimensions of the signal in the frequency domain and the time domain. Negative numbers indicate that element is the complex conjugate of the corresponding positive number. A zero indicates that element has no corresponding complex conjugate.
Examples
julia> JosephsonCircuits.printsymmetries((3,),(4,))
3-element Vector{Int64}:
0
0
0
julia> JosephsonCircuits.printsymmetries((4,),(4,))
4-element Vector{Int64}:
0
1
0
-1
julia> JosephsonCircuits.printsymmetries((3,3),(4,3))
3×3 Matrix{Int64}:
0 1 -1
0 0 0
0 2 -2
julia> JosephsonCircuits.printsymmetries((4,3),(4,3))
4×3 Matrix{Int64}:
0 2 -2
1 3 5
0 4 -4
-1 -5 -3
JosephsonCircuits.processnode
— Methodprocessnode(uniquenodedict::Dict{String, Int},
uniquenodevector::Vector{String},node)
Return the node index when given a node. Add the node string to the vector uniquenodevector
and the dictionary uniquenodedict
with the node string as the key and the node index (index at which it appears in uniquenodevector
) as the value. If "node" is not a string, make it a string.
Examples
uniquenodedict = Dict("10" =>1)
uniquenodevector = ["10"]
println(JosephsonCircuits.processnode(uniquenodedict,uniquenodevector,15))
println(uniquenodevector)
println(uniquenodedict)
# output
2
["10", "15"]
Dict("10" => 1, "15" => 2)
uniquenodedict = Dict("10" =>1)
uniquenodevector = ["10"]
println(JosephsonCircuits.processnode(uniquenodedict,uniquenodevector,:A))
println(uniquenodevector)
println(uniquenodedict)
# output
2
["10", "A"]
Dict("A" => 2, "10" => 1)
JosephsonCircuits.processnode
— Methodprocessnode(uniquenodedict::Dict{String, Int},
uniquenodevector::Vector{String},node::String)
Return the node index when given a node. Add the node string to the vector uniquenodevector
and the dictionary uniquenodedict
with the node string as the key and the node index (index at which it appears in uniquenodevector
) as the value.
Examples
uniquenodedict = Dict("10" =>1)
uniquenodevector = ["10"]
println(JosephsonCircuits.processnode(uniquenodedict,uniquenodevector,"15"))
println(uniquenodevector)
println(uniquenodedict)
# output
2
["10", "15"]
Dict("10" => 1, "15" => 2)
uniquenodedict = Dict("10" =>1)
uniquenodevector = ["10"]
println(JosephsonCircuits.processnode(uniquenodedict,uniquenodevector,"10"))
println(uniquenodevector)
println(uniquenodedict)
# output
1
["10"]
Dict("10" => 1)
JosephsonCircuits.pushval!
— Methodpushval!(V::Vector, val, c, invert::Bool)
Append the value val
of capacitance or conductance to the vector V
. Scale the value by c
. If invert = true
, append c/val
otherwise append c*val
.
Examples
julia> V = Array{Float64, 1}(undef, 0);JosephsonCircuits.pushval!(V,2.0,-1.0,false);V
1-element Vector{Float64}:
-2.0
julia> V = Array{Float64, 1}(undef, 0);JosephsonCircuits.pushval!(V,2.0,-1.0,true);V
1-element Vector{Float64}:
-0.5
JosephsonCircuits.remove_edge!
— Methodremove_edge!(g,src_node,edge_index)
Remove an edge from graph g
specified by the source node src_node
and the edge index edge_index
in the forward adjacency list.
Examples
julia> g=JosephsonCircuits.Graphs.SimpleDiGraphFromIterator(JosephsonCircuits.tuple2edge([(1,1),(2,1),(2,3)]));JosephsonCircuits.remove_edge!(g,1,1)
1
JosephsonCircuits.removeconjfreqs
— Methodremoveconjfreqs(frequencies::Frequencies{N})
Return a new Frequencies struct with the conjugate symmetric terms in the DFT or RDFT removed.
Examples
julia> JosephsonCircuits.removeconjfreqs(JosephsonCircuits.Frequencies{1}((1,), (2,), (3,), CartesianIndex{1}[CartesianIndex(1,), CartesianIndex(2,)], [(0,), (1,)]))
JosephsonCircuits.Frequencies{1}((1,), (2,), (3,), CartesianIndex{1}[CartesianIndex(1,), CartesianIndex(2,)], [(0,), (1,)])
julia> frequencies = JosephsonCircuits.Frequencies{2}((2,2), (3, 5), (4, 5), CartesianIndex{2}[CartesianIndex(1, 1), CartesianIndex(2, 1), CartesianIndex(3, 1), CartesianIndex(1, 2), CartesianIndex(2, 2), CartesianIndex(3, 2), CartesianIndex(1, 3), CartesianIndex(2, 3), CartesianIndex(3, 3), CartesianIndex(1, 4), CartesianIndex(2, 4), CartesianIndex(3, 4), CartesianIndex(1, 5), CartesianIndex(2, 5), CartesianIndex(3, 5)], [(0, 0), (1, 0), (2, 0), (0, 1), (1, 1), (2, 1), (0, 2), (1, 2), (2, 2), (0, -2), (1, -2), (2, -2), (0, -1), (1, -1), (2, -1)]);JosephsonCircuits.removeconjfreqs(frequencies).modes
11-element Vector{Tuple{Int64, Int64}}:
(0, 0)
(1, 0)
(2, 0)
(0, 1)
(1, 1)
(2, 1)
(0, 2)
(1, 2)
(2, 2)
(1, -2)
(1, -1)
julia> JosephsonCircuits.removeconjfreqs(JosephsonCircuits.calcfreqsrdft((2,2))).modes
11-element Vector{Tuple{Int64, Int64}}:
(0, 0)
(1, 0)
(2, 0)
(0, 1)
(1, 1)
(2, 1)
(0, 2)
(1, 2)
(2, 2)
(1, -2)
(1, -1)
JosephsonCircuits.removefreqs
— Methodremovefreqs(frequencies::Frequencies{N},
removecoords::AbstractVector{CartesianIndex{N}})
Return a new Frequency struct with the coordinates and modes for the modes in removemodes removed.
Examples
julia> JosephsonCircuits.removefreqs(JosephsonCircuits.calcfreqsrdft((2,)),CartesianIndex{1}[CartesianIndex(1,)])
JosephsonCircuits.Frequencies{1}((2,), (3,), (4,), CartesianIndex{1}[CartesianIndex(2,), CartesianIndex(3,)], [(1,), (2,)])
julia> JosephsonCircuits.removefreqs(JosephsonCircuits.calcfreqsrdft((2,)),CartesianIndex{1}[CartesianIndex(1,),CartesianIndex(2,),CartesianIndex(3,),CartesianIndex(4,)])
JosephsonCircuits.Frequencies{1}((2,), (3,), (4,), CartesianIndex{1}[], Tuple{Int64}[])
julia> JosephsonCircuits.removefreqs(JosephsonCircuits.calcfreqsrdft((2,)),CartesianIndex{1}[])
JosephsonCircuits.Frequencies{1}((2,), (3,), (4,), CartesianIndex{1}[CartesianIndex(1,), CartesianIndex(2,), CartesianIndex(3,)], [(0,), (1,), (2,)])
JosephsonCircuits.removefreqs
— Methodremovefreqs(frequencies::Frequencies{N},
removemodes::AbstractVector{NTuple{N,Int}})
Return a new Frequency struct with the coordinates and modes for the modes in removemodes removed.
Examples
julia> JosephsonCircuits.removefreqs(JosephsonCircuits.calcfreqsrdft((2,)),Tuple{Int64}[(2,)])
JosephsonCircuits.Frequencies{1}((2,), (3,), (4,), CartesianIndex{1}[CartesianIndex(1,), CartesianIndex(2,)], [(0,), (1,)])
julia> JosephsonCircuits.removefreqs(JosephsonCircuits.calcfreqsrdft((2,)),Tuple{Int64}[(0,),(1,),(2,),(3,)])
JosephsonCircuits.Frequencies{1}((2,), (3,), (4,), CartesianIndex{1}[], Tuple{Int64}[])
julia> JosephsonCircuits.removefreqs(JosephsonCircuits.calcfreqsrdft((2,)),Tuple{Int64}[])
JosephsonCircuits.Frequencies{1}((2,), (3,), (4,), CartesianIndex{1}[CartesianIndex(1,), CartesianIndex(2,), CartesianIndex(3,)], [(0,), (1,), (2,)])
JosephsonCircuits.showstruct
— Methodshowstruct(io::IO,out)
Recursively print the struct out
to the IOStream or IOBuffer io
.
Examples
julia> JosephsonCircuits.testshow(stdout,JosephsonCircuits.warmupnumericmatrices())
JosephsonCircuits.CircuitMatrices(sparse([1, 2, 1, 2], [1, 1, 2, 2], [1.0e-13, -1.0e-13, -1.0e-13, 1.1e-12], 2, 2), sparse([1], [1], [0.02], 2, 2), sparsevec(Int64[], Nothing[], 2), sparsevec(Int64[], Nothing[], 2), sparsevec([2], [1.0e-9], 2), sparsevec([2], [1.0e-9], 2), sparse(Int64[], Int64[], Nothing[], 2, 2), sparse(Int64[], Int64[], Nothing[], 2, 2), sparse([1, 2], [1, 2], [1, 1], 2, 2), [1], [1], [2], Int64[], 1.0e-9, Real[1, 50.0, 1.0e-13, 1.0e-9, 1.0e-12])
julia> JosephsonCircuits.testshow(IOBuffer(),JosephsonCircuits.warmupsyms())
JosephsonCircuits.sincosnl
— Methodsincosnl(am::Array{Complex{Float64},2})
Applies the junction nonlinearity to a vector of Fourier coefficients of the phases across the junction of size 2*m by (Nnodes-1) where m is the number of pump harmonics (0w, 1w, 2w, 3w, etc). To save time, this calculates both the sine and cosine nonlinearities at the same time. If the input is odd harmonics, the sine terms will also be odd harmonics the cosine terms will be even harmonics.
Examples
julia> isapprox(JosephsonCircuits.sincosnl([0 0.001+0im;0 0]),ComplexF64[1.0 + 0.0im 1.000999499833375 + 0.0im; 0.0 + 0.0im 0.0 + 0.0im])
true
julia> isapprox(JosephsonCircuits.sincosnl([0 0;0.001+0im 0;0 0;0 0; 0 0]), ComplexF64[0.99999900000025 + 0.0im 1.0 + 0.0im; 0.0009999995000000916 + 0.0im 0.0 + 0.0im; -4.999998333421463e-7 + 0.0im 0.0 + 0.0im; -1.6666664597909941e-10 + 0.0im 0.0 + 0.0im; 8.337774914934926e-14 + 0.0im 0.0 + 0.0im])
true
julia> isapprox(JosephsonCircuits.sincosnl([0 0;0.001+0im 0.25+0im;0 0;0 0; 0 0]),ComplexF64[0.99999900000025 + 0.0im 0.9384698079924576 + 0.0im; 0.0009999995000000916 + 0.0im 0.24226844566945333 + 0.0im; -4.999998333421463e-7 + 0.0im -0.03060435952740681 + 0.0im; -1.6666664597909941e-10 + 0.0im -0.0025556763673518224 + 0.0im; 8.337774914934926e-14 + 0.0im 0.0003214729527288296 + 0.0im])
true
JosephsonCircuits.sincosnloddtoboth
— Methodsincosnloddtoboth(amodd::Array{Complex{Float64},1},Nbranches::Int,m::Int)
Applies the junction nonlinearity to a vector of branch fluxes of length Nbranches*m
where m
is the number of odd pump harmonics (1w, 3w, 5w, etc). The ordering is (mode 1, node 1), (mode 2, node 1) ... (mode 1, node 2) ... Returns even AND odd terms in a 2d array with dimensions 2*m by Nbranches.
Examples
julia> isapprox(JosephsonCircuits.sincosnloddtoboth([0.5+0.0im,0,0,0],1,4),ComplexF64[0.765197686557965 + 0.0im; 0.44005058574495276 + 0.0im; -0.11490348493140057 + 0.0im; -0.019563353994648498 + 0.0im; 0.0024766387010484486 + 0.0im; 0.0002497629794614272 + 0.0im; -2.084411456066653e-5 + 0.0im; -3.0046516347986037e-6 + 0.0im;;])
true
julia> isapprox(JosephsonCircuits.sincosnloddtoboth([0.02+0.0im,0,0.01+0.0im,0],2,2),ComplexF64[0.9996000399980445 + 0.0im 0.9999000024999694 + 0.0im; 0.019996000293322436 + 0.0im 0.009999500009166587 + 0.0im; -0.00019996666853328016 + 0.0im -4.999791669583568e-5 + 0.0im; -2.6664000106757513e-6 + 0.0im -3.3332500006440685e-7 + 0.0im])
true
JosephsonCircuits.solveS!
— MethodsolveS!(Sp, Sc, portsp, portsc, gammacc, Spp, Spc, Scp, Scc,
Spp_indices, Spc_indices, Scp_indices, Scc_indices, networkdata,
nbatches, factorization, internal_ports)
In-place version of solveS
. See solveS
for description. The use- case for this function is to perform in-place updates of a network connection, for example, by changing the arrays that are referenced in networks
then recomputing the scattering parameters for the connected system.
Examples
networks = [("S1",[0.0 1.0;1.0 0.0]),("S2",[0.5 0.5;0.5 0.5])];
connections = [[("S1",1),("S2",2)]];
init = JosephsonCircuits.solveS_initialize(networks, connections);
JosephsonCircuits.solveS!(init...)
# output
(S = [0.5 0.5; 0.5 0.5], ports = [("S1", 2), ("S2", 1)], Sinternal = Float64[], portsinternal = [("S1", 1), ("S2", 2)])
References
V. A. Monaco and P. Tiberio, "Computer-Aided Analysis of Microwave Circuits," in IEEE Transactions on Microwave Theory and Techniques, vol. 22, no. 3, pp. 249-263, Mar. 1974, doi: 10.1109/TMTT.1974.1128208.
JosephsonCircuits.solveS
— MethodsolveS(networks, connections; small_splitters::Bool = true,
factorization = KLUfactorization(), internal_ports::Bool = false,
nbatches::Integer = Base.Threads.nthreads())
Perform the connections between the networks in networks
specified by the vector of vectors of tuples connections
. Return the sparse matrix of scattering parameters for the external ports S
and the external ports ports
. Also return the internal port scattering parameters Sinternal
and the internal ports portsinternal
.
Arguments
networks
: a vector of tuples of the network name, scattering parameter matrix, and optionally the ports such as [("network1name",rand(Complex{Float64},2,2))] or [("S1",[0.0 1.0;1.0 0.0]),("S2",[0.5 0.5;0.5 0.5])].connections::AbstractVector{<:AbstractVector{Tuple{T,Int}}}
: a vector of vectors of tuples of networks names and ports such as [[("S1",1),("S2",2)]] or [[("network1name",1),("network2name",2)]] where network1 and network2 are the two networks being connected and 1 and 2 are integers describing the ports to connect.
Keywords
small_splitters::Bool = true
: if true, then generate any N port splitter by combining (N-2) 3 port splitters. if false, then make the N port splitter and connect the components to it.factorization = KLUfactorization()
: use KLU factorization by default. JosephsonCircuits.LUfactorization() is another good choice. Keyword arguments can be passed to the solver as keyword arguments to these functions.internal_ports::Bool = false
: return the scattering parameters for the internal ports.nbatches::Integer = Base.Threads.nthreads()
: the number of batches to run on threads. Defaults to the number of threads with which Julia was launched.
Returns
S
: sparse matrix of scattering parameters for the external ports.ports
: the vector of tuples of network name and port number for the external ports.Sinternal
: sparse matrix of scattering parameters for the internal ports.portsinternal
: the vector of tuples of network name and port number for the internal ports.
Examples
networks = [("S1",[0.0 1.0;1.0 0.0]),("S2",[0.5 0.5;0.5 0.5])];
connections = [[("S1",1),("S2",2)]];
JosephsonCircuits.solveS(networks,connections;internal_ports=true)
# output
(S = [0.5 0.5; 0.5 0.5], ports = [("S1", 2), ("S2", 1)], Sinternal = [1.0 0.0; 0.5 0.5], portsinternal = [("S1", 1), ("S2", 2)])
networks = [("S1",[0.0 1.0;1.0 0.0]),("S2",[0.5 0.5;0.5 0.5],[("S3",5),("S3",6)])];
connections = [("S1","S3",1,6)];
JosephsonCircuits.solveS(networks,connections)
# output
(S = [0.5 0.5; 0.5 0.5], ports = [("S1", 2), ("S3", 5)], Sinternal = Float64[], portsinternal = [("S1", 1), ("S3", 6)])
References
V. A. Monaco and P. Tiberio, "Computer-Aided Analysis of Microwave Circuits," in IEEE Transactions on Microwave Theory and Techniques, vol. 22, no. 3, pp. 249-263, Mar. 1974, doi: 10.1109/TMTT.1974.1128208.
JosephsonCircuits.solveS_update!
— MethodsolveS_update!(Spp, Spc, Scp, Scc, Spp_indices, Spc_indices,
Scp_indices, Scc_indices, networkdata, i)
Update the sparse matrices Spp
, Spc
, Scp
, and Scc
using the indices from Spp_indices
, Spc_indices
, Scp_indices
, and Scc_indices
which are indices into networkdata
with frequency index i
.
JosephsonCircuits.sortnodes
— Methodsortnodes(uniquenodevector::Vector{String},
nodeindexvector::Vector{Int};sorting=:name)
Sort the unique node names in uniquenodevector
according to the specified sorting scheme, always placing the ground node at the beginning.
Return the sorted uniquenodevector
and nodeindexvector
(with the vector reshaped from a vector of length 2*Nnodes into a matrix with dimensions 2 by Nnodes).
Keywords
sorting = :name
: Sort the vector of strings. This always works but leads to results like "101" comes before "11".sorting = :number
: Convert the node strings to integer and sort by these (this errors if the nodes names cannot be converted to integers).sorting = :none
: Don't perform any sorting except to place the ground node first.
Examples
julia> nodenames,nodeindexarray=JosephsonCircuits.sortnodes(["101","0","111","11"],[1,2,1,2,1,2,1,3,3,2,3,2,4,1],sorting=:none);println(nodenames);println(nodeindexarray);
["0", "101", "111", "11"]
[2 2 2 2 3 3 4; 1 1 1 3 1 1 2]
julia> nodenames,nodeindexarray=JosephsonCircuits.sortnodes(["101","0","111","11"],[1,2,1,2,1,2,1,3,3,2,3,2,4,1],sorting=:name);println(nodenames);println(nodeindexarray);
["0", "101", "11", "111"]
[2 2 2 2 4 4 3; 1 1 1 4 1 1 2]
julia> nodenames,nodeindexarray=JosephsonCircuits.sortnodes(["101","0","111","11"],[1,2,1,2,1,2,1,3,3,2,3,2,4,1],sorting=:number);println(nodenames);println(nodeindexarray);
["0", "11", "101", "111"]
[3 3 3 3 4 4 2; 1 1 1 4 1 1 3]
julia> nodenames,nodeindexarray=JosephsonCircuits.sortnodes(["1", "0", "2"],[1, 2, 1, 2, 1, 2, 1, 2, 0, 0, 3, 2, 3, 2],sorting=:number);println(nodenames);println(nodeindexarray);
["0", "1", "2"]
[2 2 2 2 0 3 3; 1 1 1 1 0 1 1]
JosephsonCircuits.spaddkeepzeros
— Methodspaddkeepzeros(A::SparseMatrixCSC, B::SparseMatrixCSC)
Add sparse matrices A
and B
and return the result, keeping any structural zeros, unlike the default Julia sparse matrix addition functions.
Examples
julia> A = JosephsonCircuits.SparseArrays.sprand(10,10,0.2); B = JosephsonCircuits.SparseArrays.sprand(10,10,0.2);JosephsonCircuits.spaddkeepzeros(A,B) == A+B
true
A = JosephsonCircuits.SparseArrays.sparse([1,2,1], [1,2,2], [1,2,0],2,2);
B = JosephsonCircuits.SparseArrays.sparse([1,2], [1,2], [1,1],2,2);
JosephsonCircuits.spaddkeepzeros(A,B)
# output
2×2 SparseArrays.SparseMatrixCSC{Int64, Int64} with 3 stored entries:
2 0
⋅ 3
JosephsonCircuits.sparseadd!
— Methodsparseadd!(A::SparseMatrixCSC, c::Number, Ad::Diagonal,
As::SparseMatrixCSC, indexmap::Vector)
Add sparse matrices A
and c*Ad*As
and return the result in A
. The sparse matrix As
must have nonzero entries only in a subset of the positions in A
which have nonzero (structural zeros are ok) entries.
Examples
A = JosephsonCircuits.SparseArrays.sparse([1,2,1], [1,2,2], [1,2,-3],2,2)
Ad = JosephsonCircuits.LinearAlgebra.Diagonal([1,-2])
As = JosephsonCircuits.SparseArrays.sparse([1,1], [1,2], [3,4],2,2)
indexmap = JosephsonCircuits.sparseaddmap(A,As)
JosephsonCircuits.sparseadd!(A,2,Ad,As,indexmap)
A
# output
2×2 SparseArrays.SparseMatrixCSC{Int64, Int64} with 3 stored entries:
7 5
⋅ 2
JosephsonCircuits.sparseadd!
— Methodsparseadd!(A::SparseMatrixCSC, c::Number, As::SparseMatrixCSC,
Ad::Diagonal, indexmap)
Add sparse matrices A
and c*As*Ad
and return the result in A
. The sparse matrix As
must have nonzero entries only in a subset of the positions in A
which have nonzero (structural zeros are ok) entries.
Examples
A = JosephsonCircuits.SparseArrays.sparse([1,2,1], [1,2,2], [1,2,-3],2,2)
As = JosephsonCircuits.SparseArrays.sparse([1,1], [1,2], [3,4],2,2)
Ad = JosephsonCircuits.LinearAlgebra.Diagonal([1,-2])
indexmap = JosephsonCircuits.sparseaddmap(A,As)
JosephsonCircuits.sparseadd!(A,2,As,Ad,indexmap)
A
# output
2×2 SparseArrays.SparseMatrixCSC{Int64, Int64} with 3 stored entries:
7 -19
⋅ 2
JosephsonCircuits.sparseadd!
— Methodsparseadd!(A::SparseMatrixCSC, c::Number, As::SparseMatrixCSC, indexmap)
Add sparse matrices A
and c*As
and return the result in A
. The sparse matrix As
must have nonzero entries only in a subset of the positions in A
which have nonzero (structural zeros are ok) entries.
Examples
A = JosephsonCircuits.SparseArrays.sparse([1,2,1], [1,2,2], [1,2,-3],2,2)
As = JosephsonCircuits.SparseArrays.sparse([1,1], [1,2], [3,4],2,2)
indexmap = JosephsonCircuits.sparseaddmap(A,As)
JosephsonCircuits.sparseadd!(A,2,As,indexmap)
A
# output
2×2 SparseArrays.SparseMatrixCSC{Int64, Int64} with 3 stored entries:
7 5
⋅ 2
JosephsonCircuits.sparseadd!
— Methodsparseadd!(A::SparseMatrixCSC, As::SparseMatrixCSC, indexmap)
Add sparse matrices A
and As
and return the result in A
without performing any allocations. This is only possible if the positions of elements in As
are a subset of the positions of elements in A
. The indexmap
can be generated with sparseaddmap
.
Examples
A = JosephsonCircuits.SparseArrays.sparse([1,2,1], [1,2,2], [1,2,-3],2,2)
As = JosephsonCircuits.SparseArrays.sparse([1,1], [1,2], [3,4],2,2)
indexmap = JosephsonCircuits.sparseaddmap(A,As)
JosephsonCircuits.sparseadd!(A,As,indexmap)
A
# output
2×2 SparseArrays.SparseMatrixCSC{Int64, Int64} with 3 stored entries:
4 1
⋅ 2
JosephsonCircuits.sparseaddconjsubst!
— Methodsparseaddconjsubst!(A::SparseMatrixCSC, c::Number, As::SparseMatrixCSC,
Ad::Diagonal, indexmap, conjflag::Diagonal, wmodesm::Diagonal,
freqsubstindices::Vector, symfreqvar)
Perform the operation A+c*As*Ad
and return the result in A
. Take the complex conjugate of As
for any column where conjflag = true
.
The sparse matrix As
must have nonzero elements only in a subset of the positions in A
which has nonzero lements.
Examples
A = JosephsonCircuits.SparseArrays.sparse([1,2,1], [1,2,2], [1.0+1.0im,2.0+1.0im,-3.0+0.0im],2,2)
Ad = JosephsonCircuits.LinearAlgebra.Diagonal([1,-2])
As = JosephsonCircuits.SparseArrays.sparse([1,1], [1,2], [3.0+2.0im,4.0+3.0im],2,2)
wmodesm = JosephsonCircuits.LinearAlgebra.Diagonal([-1,1])
indexmap = JosephsonCircuits.sparseaddmap(A,As)
freqsubstindices = JosephsonCircuits.symbolicindices(As)
JosephsonCircuits.sparseaddconjsubst!(A,2,As,Ad,indexmap,wmodesm .< 0,wmodesm,freqsubstindices,nothing)
A
# output
2×2 SparseArrays.SparseMatrixCSC{ComplexF64, Int64} with 3 stored entries:
7.0-3.0im -19.0-12.0im
⋅ 2.0+1.0im
JosephsonCircuits.sparseaddmap
— Methodsparseaddmap(A::SparseMatrixCSC, B::SparseMatrixCSC)
Return a vector of length nnz(B)
which maps the indices of elements of B
in B.nzval
to the corresponding indices in A.nzval
. The sparse matrix B
must have elements in a subset of the positions in A
which have nonzero entries (structural zeros are elements).
Examples
A = JosephsonCircuits.SparseArrays.sparse([1,2,1], [1,2,2], [1,2,-3],2,2)
As = JosephsonCircuits.SparseArrays.sparse([1], [2], [4],2,2)
JosephsonCircuits.sparseaddmap(A,As)
# output
1-element Vector{Int64}:
2
A = JosephsonCircuits.SparseArrays.sparse([1,2,1], [1,2,2], [1,2,-3],2,2)
As = JosephsonCircuits.SparseArrays.sparse([1,2], [1,2], [4,2],2,2)
JosephsonCircuits.sparseaddmap(A,As)
# output
2-element Vector{Int64}:
1
3
JosephsonCircuits.spice_hb_load
— Methodspice_hb_load(filename)
Load a Xyce harmonic balance simulation.
JosephsonCircuits.spice_raw_load
— Methodspice_raw_load(filename)
Parse the binary raw output file from WRSPICE or Xyce. Tested for transient analysis and frequency domain analysis. The file format is documented in the WRSPICE manual in Appendix 1, File Formats, A.1 Rawfile Format.
The Xyce rawfile format is very similar and described here.
The function outputs a header, the times/frequencies, the currents, and the voltages. The voltage and current arrays have dimensions nVoltages by nPoints and nCurrents by nPoints.
JosephsonCircuits.spice_run
— Methodspice_run(input::AbstractVector,spicecmd; ntasks = Threads.nthreads())
If the input to wrspice_run() is an array of strings, then call multiple processes in parallel. The number of parallel processes is decided from Threads.nthreads(). It can be changed manually.
JosephsonCircuits.spice_run
— Methodspice_run(input, spicecmd::String)
Argument is a string or command containing the input commands for wrspice. This function saves the string to disk, runs spice, parses the results with wrsplice_load(), then returns those parsed results.
The input should not should have a file name listed after the write command in the .control block so that we can specify the raw output file with a command line argument.
JosephsonCircuits.spmatmul!
— Methodspmatmul!(C::SparseMatrixCSC, A::SparseMatrixCSC, B::SparseMatrixCSC,
xb::Vector{Bool})
Non-allocating sparse matrix multiplication of A
and B
when sparsity pattern of product C
is known. Based on spmatmul from SparseArrays.jl.
Examples
julia> a = JosephsonCircuits.sprand(100,100,0.1);b = JosephsonCircuits.sprand(100,100,0.1);c = a*b; d = copy(c);xb = fill(false, size(a,1));JosephsonCircuits.spmatmul!(c,a,b,xb);c == d
true
JosephsonCircuits.sprandsubset
— Functionsprandsubset(A::SparseMatrixCSC, p::AbstractFloat, dropzeros = true)
Given a sparse matrix A
, return a sparse matrix with random values in some fraction of the non-zero elements with probability p. If dropzeros = false
, then the zeros will be retained as structural zeros otherwise they are dropped.
This is used for testing non-allocating sparse matrix addition.
Examples
A = JosephsonCircuits.SparseArrays.sprand(2,2,0.5)
B = JosephsonCircuits.sprandsubset(A, 0.1)
length(A.nzval) >= length(B.nzval)
# output
true
A = JosephsonCircuits.SparseArrays.sprand(100,100,0.5)
B = JosephsonCircuits.sprandsubset(A, 0.1)
length(A.nzval) >= length(B.nzval)
# output
true
JosephsonCircuits.storeuniqueloops!
— Methodstoreuniqueloops!(lvarray, vmap, ul)
Examples
julia> lvarray = Vector{Int}[];JosephsonCircuits.storeuniqueloops!(lvarray,[1, 2, 3],[[1,2,3]]);lvarray
1-element Vector{Vector{Int64}}:
[1, 2, 3]
julia> lvarray = Vector{Int}[];JosephsonCircuits.storeuniqueloops!(lvarray,[1, 2, 3],Vector{Int64}[]);lvarray
1-element Vector{Vector{Int64}}:
[]
JosephsonCircuits.stripcommentslowercase!
— Methodstripcommentslowercase!(comments::Vector{String},line::String)
Append the comment portion of a line line
of a Touchstone file to the vector comments
. Return the line with the comments removed and made lowercase.
Examples
julia> comments=String[];println(JosephsonCircuits.stripcommentslowercase!(comments,"! This is a comment"));println(comments)
[" This is a comment"]
julia> comments=String[];println(JosephsonCircuits.stripcommentslowercase!(comments,"This is a !comment"));println(comments)
this is a
["comment"]
JosephsonCircuits.sumbranchvalues!
— Methodsumbranchvalues!(type::Symbol, node1::Int, node2::Int,componentvalues::Vector,
countdict, indexdict)
Given a branch and a type, return the sum of all of the values of the same type and branch. The sum will behave differently depending on the type.
Examples
vvn = Real[1, 50.0, 1.0e-13, 2.0e-9, 2.0e-9, 5.0e-13, 5.0e-13, 0.1]
countdict = Dict((:L, 1, 3) => 2, (:R, 1, 2) => 1, (:P, 1, 2) => 1, (:C, 1, 3) => 2, (:C, 2, 3) => 1, (:I, 1, 3) => 1)
indexdict = Dict((:C, 2, 3, 1) => 3, (:C, 1, 3, 1) => 6, (:R, 1, 2, 1) => 2, (:L, 1, 3, 1) => 4, (:C, 1, 3, 2) => 7, (:L, 1, 3, 2) => 5, (:P, 1, 2, 1) => 1, (:I, 1, 3, 1) => 8)
println(JosephsonCircuits.sumbranchvalues!(:C, 1, 3, vvn, countdict, indexdict))
# output
(true, 1.0e-12, 6)
JosephsonCircuits.sumvalues
— Methodsumvalues(type::Symbol, value1, value2)
Sum together two values in different ways depending on the circuit component type.
Examples
julia> JosephsonCircuits.sumvalues(:L, 1.0, 4.0)
0.8
julia> JosephsonCircuits.sumvalues(:Lj, 1.0, 4.0)
0.8
julia> JosephsonCircuits.sumvalues(:C, 1.0, 4.0)
5.0
julia> JosephsonCircuits.sumvalues(:K, 1.0, 4.0)
5.0
JosephsonCircuits.symbolicindices
— Methodsymbolicindices(A)
Return the indices in A.nzval
where the elements of the matrix A
are symbolic variables.
Examples
julia> @variables w;A = JosephsonCircuits.SparseArrays.sparse([1,2,1], [1,2,2], [w,1.0,3*w+1]);println(A.nzval);JosephsonCircuits.symbolicindices(A)
Num[w, 1 + 3w, 1.0]
2-element Vector{Int64}:
1
2
julia> A = JosephsonCircuits.SparseArrays.sparse([1,2,1], [1,2,2], [1,1.0,2+3im]);JosephsonCircuits.symbolicindices(A)
Int64[]
JosephsonCircuits.symbolicmatrices
— Methodsymbolicmatrices(circuit; Nmodes = 1, sorting = :number)
Return the symbolic matrices describing the circuit properties.
See also CircuitMatrices
, numericmatrices
, calcCn
, calcGn
, calcLb
,calcLjb
, calcMb
, calcinvLn
, calcLmean
, calcportindicesnumbers
, calcportimpedanceindices
, and calcnoiseportimpedanceindices
.
Examples
@variables Ipump Rleft Cc Lj Cj
circuit = Vector{Tuple{String,String,String,Num}}(undef,0)
push!(circuit,("P1","1","0",1))
push!(circuit,("I1","1","0",Ipump))
push!(circuit,("R1","1","0",Rleft))
push!(circuit,("C1","1","2",Cc))
push!(circuit,("Lj1","2","0",Lj))
push!(circuit,("C2","2","0",Cj))
JosephsonCircuits.testshow(stdout,symbolicmatrices(circuit))
# output
JosephsonCircuits.CircuitMatrices(sparse([1, 2, 1, 2], [1, 1, 2, 2], SymbolicUtils.BasicSymbolic{Real}[Cc, -Cc, -Cc, Cc + Cj], 2, 2), sparse([1], [1], SymbolicUtils.BasicSymbolic{Real}[1 / Rleft], 2, 2), sparsevec(Int64[], Nothing[], 2), sparsevec(Int64[], Nothing[], 2), sparsevec([2], SymbolicUtils.BasicSymbolic{Real}[Lj], 2), sparsevec([2], SymbolicUtils.BasicSymbolic{Real}[Lj], 2), sparse(Int64[], Int64[], Nothing[], 2, 2), sparse(Int64[], Int64[], Nothing[], 2, 2), sparse([1, 2], [1, 2], [1, 1], 2, 2), [1], [1], [3], Int64[], Lj, Any[1, Ipump, Rleft, Cc, Lj, Cj])
@variables Ipump Rleft Cc Lj Cj
circuit = Vector{Tuple{String,String,String,Num}}(undef,0)
push!(circuit,("P1","1","0",1))
push!(circuit,("I1","1","0",Ipump))
push!(circuit,("R1","1","0",Rleft))
push!(circuit,("C1","1","2",Cc))
push!(circuit,("Lj1","2","0",Lj))
push!(circuit,("C2","2","0",Cj))
psc = JosephsonCircuits.parsesortcircuit(circuit)
cg = JosephsonCircuits.calccircuitgraph(psc)
JosephsonCircuits.testshow(stdout,symbolicmatrices(psc, cg))
# output
JosephsonCircuits.CircuitMatrices(sparse([1, 2, 1, 2], [1, 1, 2, 2], SymbolicUtils.BasicSymbolic{Real}[Cc, -Cc, -Cc, Cc + Cj], 2, 2), sparse([1], [1], SymbolicUtils.BasicSymbolic{Real}[1 / Rleft], 2, 2), sparsevec(Int64[], Nothing[], 2), sparsevec(Int64[], Nothing[], 2), sparsevec([2], SymbolicUtils.BasicSymbolic{Real}[Lj], 2), sparsevec([2], SymbolicUtils.BasicSymbolic{Real}[Lj], 2), sparse(Int64[], Int64[], Nothing[], 2, 2), sparse(Int64[], Int64[], Nothing[], 2, 2), sparse([1, 2], [1, 2], [1, 1], 2, 2), [1], [1], [3], Int64[], Lj, Any[1, Ipump, Rleft, Cc, Lj, Cj])
JosephsonCircuits.testshow
— Methodtestshow(io::IO,S)
Print S
to the IOStream or IOBuffer io
. This is used to generate the inputs for testing purposes. The default show
function doesn't always produce an output which can be evaluated as the input. For example, for sparse vectors.
Examples
julia> JosephsonCircuits.testshow(stdout,JosephsonCircuits.SparseArrays.sparsevec([1],[2],3))
sparsevec([1], [2], 3)
julia> JosephsonCircuits.testshow(stdout,JosephsonCircuits.SparseArrays.sparsevec([],Nothing[],3))
sparsevec(Int64[], Nothing[], 3)
julia> JosephsonCircuits.testshow(IOBuffer(),JosephsonCircuits.AxisKeys.KeyedArray(rand(Int8, 2,10), ([:a, :b], 10:10:100)))
JosephsonCircuits.touchstone_file
— Methodtouchstone_file(f::Vector{Float64}, N::Array{Complex{Float64}};
frequencyunit::String = "GHz",
parameter::String = "S",
format::String = "MA",
R::Float64 = 50.0,
version::Float64 = 2.0,
twoportdataorder::String = "",
numberofnoisefrequencies::Int = 0,
reference::Vector{Float64} = Float64[],
information::Vector{String} = String[],
matrixformat::String = "Full",
mixedmodeorder::Vector{Tuple{Char, Vector{Int}}} = Tuple{Char, Vector{Int}}[],
comments::Vector{String} = String[],
noisedata::Vector{Float64} = Float64[])
Generate a TouchstoneFile struct from the frequency vector f
in units of Hz and the complex network data array N
where the frequency axis is the last dimension. All other arguments are optional.
JosephsonCircuits.touchstone_load
— MethodJosephsonCircuits.touchstone_parse
— Methodtouchstone_parse(io::IO)
Parse the Touchstone file described by the IOBuffer or IOStream io
.
References to the 1.1 spec and the 2.0 spec.
Examples
str="!Example 1:
!1-port S-parameter file, single frequency point
# MHz S MA R 50
!freq magS11 angS11
2.000 0.894 -12.136";
println(str);
JosephsonCircuits.touchstone_parse(IOBuffer(str))
# output
!Example 1:
!1-port S-parameter file, single frequency point
# MHz S MA R 50
!freq magS11 angS11
2.000 0.894 -12.136
JosephsonCircuits.TouchstoneFile([2.0e6], ComplexF64[0.874020294860635 - 0.18794819544685323im;;;], "mhz", "s", "ma", 50.0, 1.0, 1, "12_21", 1, 0, [50.0], String[], "Full", Tuple{Char, Vector{Int64}}[], ["Example 1:", "1-port S-parameter file, single frequency point", "freq magS11 angS11"], [2.0, 0.894, -12.136], Float64[])
str="!Example 4 (Version 2.0):
! 4-port S-parameter data
! Default impedance is overridden by [Reference]
! Data cannot be represented using 1.0 syntax
! Note that the [Reference] keyword arguments appear on a separate line
[Version] 2.0
# GHz S MA R 50
[Number of Ports] 4
[Reference]
50 75 0.01 0.01
[Number of Frequencies] 1
[Network Data]
5.00000 0.60 161.24 0.40 -42.20 0.42 -66.58 0.53 -79.34 !row 1
0.40 -42.20 0.60 161.20 0.53 -79.34 0.42 -66.58 !row 2
0.42 -66.58 0.53 -79.34 0.60 161.24 0.40 -42.20 !row 3
0.53 -79.34 0.42 -66.58 0.40 -42.20 0.60 161.24 !row 4";
println(str);
JosephsonCircuits.touchstone_parse(IOBuffer(str))
# output
!Example 4 (Version 2.0):
! 4-port S-parameter data
! Default impedance is overridden by [Reference]
! Data cannot be represented using 1.0 syntax
! Note that the [Reference] keyword arguments appear on a separate line
[Version] 2.0
# GHz S MA R 50
[Number of Ports] 4
[Reference]
50 75 0.01 0.01
[Number of Frequencies] 1
[Network Data]
5.00000 0.60 161.24 0.40 -42.20 0.42 -66.58 0.53 -79.34 !row 1
0.40 -42.20 0.60 161.20 0.53 -79.34 0.42 -66.58 !row 2
0.42 -66.58 0.53 -79.34 0.60 161.24 0.40 -42.20 !row 3
0.53 -79.34 0.42 -66.58 0.40 -42.20 0.60 161.24 !row 4
JosephsonCircuits.TouchstoneFile([5.0e9], ComplexF64[-0.5681244079815996 + 0.1929628385351877im 0.29632183851470006 - 0.2686882357291961im 0.16693665375723588 - 0.38539869438327984im 0.09803970583787712 - 0.5208533537179372im; 0.29632183851470006 - 0.2686882357291961im -0.5679895560694177 + 0.1933594171383067im 0.09803970583787712 - 0.5208533537179372im 0.16693665375723588 - 0.38539869438327984im; 0.16693665375723588 - 0.38539869438327984im 0.09803970583787712 - 0.5208533537179372im -0.5681244079815996 + 0.1929628385351877im 0.29632183851470006 - 0.2686882357291961im; 0.09803970583787712 - 0.5208533537179372im 0.16693665375723588 - 0.38539869438327984im 0.29632183851470006 - 0.2686882357291961im -0.5681244079815996 + 0.1929628385351877im;;;], "ghz", "s", "ma", 50.0, 2.0, 4, "12_21", 1, 0, [50.0, 75.0, 0.01, 0.01], String[], "Full", Tuple{Char, Vector{Int64}}[], ["Example 4 (Version 2.0):", " 4-port S-parameter data", " Default impedance is overridden by [Reference]", " Data cannot be represented using 1.0 syntax", " Note that the [Reference] keyword arguments appear on a separate line", "row 1", "row 2", "row 3", "row 4"], [5.0, 0.6, 161.24, 0.4, -42.2, 0.42, -66.58, 0.53, -79.34, 0.4 … 0.4, -42.2, 0.53, -79.34, 0.42, -66.58, 0.4, -42.2, 0.6, 161.24], Float64[])
JosephsonCircuits.touchstone_save
— Methodtouchstone_save(filename::String,frequencies::AbstractArray,
N::AbstractArray;version=1.0,reference=[50.0,50.0],R = 50.0,format="RI",
comments=[""],twoportdataorder="12_21",matrixformat="Full",frequencyunit="Hz")
Write a file in the Touchstone format. Standards compliant except does not support writing noise data.
JosephsonCircuits.touchstone_write
— Methodtouchstone_write(io::IO, frequencies::AbstractVector, N::AbstractArray;
version=1.0, reference=[50.0,50.0], R = 50.0, format="RI",
parameter = "S", comments=[""], twoportdataorder="12_21",
matrixformat="Full", frequencyunit="Hz")
Write a Touchstone file to the IOStream or IOBuffer io
.
Examples
julia> io = IOBuffer();JosephsonCircuits.touchstone_write(io, [1.0e9, 2.0e9, 10.0e9], [0.3926 - 0.1211im -0.0003 - 0.0021im; -0.0003 - 0.0021im 0.3926 - 0.1211im;;; 0.3517 - 0.3054im -0.0096 - 0.0298im; -0.0096 - 0.0298im 0.3517 - 0.3054im;;; 0.3419 + 0.3336im -0.0134 + 0.0379im; -0.0134 + 0.0379im 0.3419 + 0.3336im];version=1.0,R=50.0,format="RI",frequencyunit="Hz",comments=["Example 4:","2-port S-parameter file, three frequency points"]);println(String(take!(io)))
!Example 4:
!2-port S-parameter file, three frequency points
# Hz S RI R 50.0
! freq ReS11 ImS11 ReS21 ImS21 ReS12 ImS12 ReS22 ImS22
1.0e9 0.3926 -0.1211 -0.0003 -0.0021 -0.0003 -0.0021 0.3926 -0.1211
2.0e9 0.3517 -0.3054 -0.0096 -0.0298 -0.0096 -0.0298 0.3517 -0.3054
1.0e10 0.3419 0.3336 -0.0134 0.0379 -0.0134 0.0379 0.3419 0.3336
julia> io = IOBuffer();JosephsonCircuits.touchstone_write(io, [1.0e9, 2.0e9, 10.0e9], [0.3926 - 0.1211im -0.0003 - 0.0021im; -0.0003 - 0.0021im 0.3926 - 0.1211im;;; 0.3517 - 0.3054im -0.0096 - 0.0298im; -0.0096 - 0.0298im 0.3517 - 0.3054im;;; 0.3419 + 0.3336im -0.0134 + 0.0379im; -0.0134 + 0.0379im 0.3419 + 0.3336im];version=2.0,R=50.0,format="RI",frequencyunit="Hz",comments=["Example 4:","2-port S-parameter file, three frequency points"]);println(String(take!(io)))
!Example 4:
!2-port S-parameter file, three frequency points
[Version] 2.0
# Hz S RI R 50.0
[Number of Ports] 2
[Two-Port Data Order] 12_21
[Number of Frequencies] 3
[Reference] 50.0 50.0
[Network Data]
! freq ReS11 ImS11 ReS12 ImS12 ReS21 ImS21 ReS22 ImS22
1.0e9 0.3926 -0.1211 -0.0003 -0.0021 -0.0003 -0.0021 0.3926 -0.1211
2.0e9 0.3517 -0.3054 -0.0096 -0.0298 -0.0096 -0.0298 0.3517 -0.3054
1.0e10 0.3419 0.3336 -0.0134 0.0379 -0.0134 0.0379 0.3419 0.3336
[End]
JosephsonCircuits.touchstone_write
— Methodtouchstone_write(io::IO, ts::TouchstoneFile)
Write a Touchstone file specified by the TouchstoneFile object ts
to the IOStream or IOBuffer io
.
JosephsonCircuits.truncfreqs
— Methodtruncfreqs(frequencies::Frequencies;
dc = false, odd = true, even = false, maxintermodorder = Inf)
Return a new Frequencies struct with the coordinates and modes truncated according to the user specified criteria.
Examples
julia> JosephsonCircuits.truncfreqs(JosephsonCircuits.calcfreqsrdft((3,3));maxintermodorder=2).modes
12-element Vector{Tuple{Int64, Int64}}:
(0, 0)
(1, 0)
(2, 0)
(3, 0)
(0, 1)
(1, 1)
(0, 2)
(0, 3)
(0, -3)
(0, -2)
(0, -1)
(1, -1)
julia> JosephsonCircuits.truncfreqs(JosephsonCircuits.calcfreqsrdft((3,3));dc=false,even=false,maxintermodorder=3).modes
10-element Vector{Tuple{Int64, Int64}}:
(1, 0)
(3, 0)
(0, 1)
(2, 1)
(1, 2)
(0, 3)
(0, -3)
(1, -2)
(0, -1)
(2, -1)
julia> JosephsonCircuits.truncfreqs(JosephsonCircuits.calcfreqsrdft((3,3));maxintermodorder=2)
JosephsonCircuits.Frequencies{2}((3, 3), (4, 7), (6, 7), CartesianIndex{2}[CartesianIndex(1, 1), CartesianIndex(2, 1), CartesianIndex(3, 1), CartesianIndex(4, 1), CartesianIndex(1, 2), CartesianIndex(2, 2), CartesianIndex(1, 3), CartesianIndex(1, 4), CartesianIndex(1, 5), CartesianIndex(1, 6), CartesianIndex(1, 7), CartesianIndex(2, 7)], [(0, 0), (1, 0), (2, 0), (3, 0), (0, 1), (1, 1), (0, 2), (0, 3), (0, -3), (0, -2), (0, -1), (1, -1)])
JosephsonCircuits.tryfactorize!
— Methodtryfactorize!(cache::FactorizationCache,
factorization::Factorization, A::AbstractArray)
Factorize the matrix A
using the factorization from factorization
and store the result in cache
. Attempt to reuse the symbolic factorization. Redo the symbolic factorization if we get a SingularException.
JosephsonCircuits.trysolve!
— Methodtrysolve!(x,factorization,b)
First try to solve a linear system using ldiv! then if it errors, use . The motivation for this function is some factorizations such as qr
with sparse matrices don't support ldiv!.
JosephsonCircuits.tuple2edge
— Methodtuple2edge(tuplevector::Vector{Tuple{Int, Int, Int, Int}})
Converts a vector of edges specified with tuples of integers to a vector of Graphs edges.
Examples
julia> JosephsonCircuits.tuple2edge([(1,2,3,4),(5,6,7,8)])
2-element Vector{Tuple{Graphs.SimpleGraphs.SimpleEdge{Int64}, Graphs.SimpleGraphs.SimpleEdge{Int64}}}:
(Edge 1 => 2, Edge 3 => 4)
(Edge 5 => 6, Edge 7 => 8)
JosephsonCircuits.tuple2edge
— Methodtuple2edge(tuplevector::Vector{Tuple{Int, Int}})
Converts a vector of edges specified with tuples of integers to a vector of Graphs edges.
Examples
julia> JosephsonCircuits.tuple2edge([(1,2),(3,4)])
2-element Vector{Graphs.SimpleGraphs.SimpleEdge{Int64}}:
Edge 1 => 2
Edge 3 => 4
JosephsonCircuits.tuple2edge
— Methodtuple2edge(tupledict::Dict{Tuple{Int, Int, Int, Int},T})
Converts a dictionary whose keys are edges specified by tuples of integers to a dictionary whose keys are Graphs edges. The values associated with each key are preserved.
Examples
julia> JosephsonCircuits.tuple2edge(Dict{Tuple{Int, Int, Int, Int}, Int}((1, 2, 3, 4) => 1, (5, 6, 7, 8) => 3))
Dict{Tuple{Graphs.SimpleGraphs.SimpleEdge{Int64}, Graphs.SimpleGraphs.SimpleEdge{Int64}}, Int64} with 2 entries:
(Edge 1 => 2, Edge 3 => 4) => 1
(Edge 5 => 6, Edge 7 => 8) => 3
julia> JosephsonCircuits.tuple2edge(Dict{Tuple{Int, Int, Int, Int}, Float64}((1, 2, 3, 4) => 1, (5, 6, 7, 8) => 3))
Dict{Tuple{Graphs.SimpleGraphs.SimpleEdge{Int64}, Graphs.SimpleGraphs.SimpleEdge{Int64}}, Float64} with 2 entries:
(Edge 1 => 2, Edge 3 => 4) => 1.0
(Edge 5 => 6, Edge 7 => 8) => 3.0
julia> JosephsonCircuits.tuple2edge(Dict{Tuple{Int, Int, Int, Int}, Complex{Float64}}((1, 2, 3, 4) => 1, (5, 6, 7, 8) => 3))
Dict{Tuple{Graphs.SimpleGraphs.SimpleEdge{Int64}, Graphs.SimpleGraphs.SimpleEdge{Int64}}, ComplexF64} with 2 entries:
(Edge 1 => 2, Edge 3 => 4) => 1.0+0.0im
(Edge 5 => 6, Edge 7 => 8) => 3.0+0.0im
julia> JosephsonCircuits.tuple2edge(Dict{Tuple{Int, Int, Int, Int}, Any}((1, 2, 3, 4) => 1, (5, 6, 7, 8) => 3))
Dict{Tuple{Graphs.SimpleGraphs.SimpleEdge{Int64}, Graphs.SimpleGraphs.SimpleEdge{Int64}}, Any} with 2 entries:
(Edge 1 => 2, Edge 3 => 4) => 1
(Edge 5 => 6, Edge 7 => 8) => 3
JosephsonCircuits.tuple2edge
— Methodtuple2edge(tupledict::Dict{Tuple{Int, Int},T})
Converts a dictionary whose keys are edges specified by tuples of integers to a dictionary whose keys are Graphs edges. The values associated with each key are preserved.
Examples
julia> JosephsonCircuits.tuple2edge(Dict{Tuple{Int, Int}, Int}((1, 2) => 1, (3, 4) => 3, (2, 3) => 2))
Dict{Graphs.SimpleGraphs.SimpleEdge{Int64}, Int64} with 3 entries:
Edge 1 => 2 => 1
Edge 3 => 4 => 3
Edge 2 => 3 => 2
julia> JosephsonCircuits.tuple2edge(Dict{Tuple{Int, Int}, Float64}((1, 2) => 1, (3, 4) => 3, (2, 3) => 2))
Dict{Graphs.SimpleGraphs.SimpleEdge{Int64}, Float64} with 3 entries:
Edge 1 => 2 => 1.0
Edge 3 => 4 => 3.0
Edge 2 => 3 => 2.0
julia> JosephsonCircuits.tuple2edge(Dict{Tuple{Int, Int}, Complex{Float64}}((1, 2) => 1, (3, 4) => 3, (2, 3) => 2))
Dict{Graphs.SimpleGraphs.SimpleEdge{Int64}, ComplexF64} with 3 entries:
Edge 1 => 2 => 1.0+0.0im
Edge 3 => 4 => 3.0+0.0im
Edge 2 => 3 => 2.0+0.0im
julia> JosephsonCircuits.tuple2edge(Dict{Tuple{Int, Int}, Any}((1, 2) => 1, (3, 4) => 3, (2, 3) => 2))
Dict{Graphs.SimpleGraphs.SimpleEdge{Int64}, Any} with 3 entries:
Edge 1 => 2 => 1
Edge 3 => 4 => 3
Edge 2 => 3 => 2
JosephsonCircuits.updateAoLjbm!
— MethodupdateAoLjbm!(AoLjbm::SparseMatrixCSC, Am, Ljb::SparseVector, Lmean, Nmodes,
Nbranches)
Examples
@variables Lj1 Lj2 A11 A12 A21 A22 A31 A32;
AoLjbm = JosephsonCircuits.calcAoLjbm([A11 A12;A21 A22;A31 A32],JosephsonCircuits.SparseArrays.sparsevec([1,2],[Lj1,Lj2]),1,2,2);
AoLjbmcopy = copy(AoLjbm);
AoLjbmcopy.nzval .= 0;
JosephsonCircuits.updateAoLjbm!(AoLjbmcopy,[A11 A12;A21 A22;A31 A32],JosephsonCircuits.SparseArrays.sparsevec([1,2],[Lj1,Lj2]),1,2,2)
all(AoLjbmcopy.nzval .- AoLjbm.nzval .== 0)
# output
true
@variables Lj1 Lj2 A11 A12 A21 A22 A31 A32;
AoLjbm = JosephsonCircuits.calcAoLjbm([A11 A12;A21 A22;A31 A32],JosephsonCircuits.SparseArrays.sparsevec([1,2],[Lj1,Lj2]),1,3,2);
AoLjbmcopy = copy(AoLjbm);
AoLjbmcopy.nzval .= 0;
JosephsonCircuits.updateAoLjbm!(AoLjbmcopy,[A11 A12;A21 A22;A31 A32],JosephsonCircuits.SparseArrays.sparsevec([1,2],[Lj1,Lj2]),1,3,2)
all(AoLjbmcopy.nzval .- AoLjbm.nzval .== 0)
# output
true
JosephsonCircuits.updateAoLjbm2!
— MethodupdateAoLjbm2!(AoLjbm::SparseMatrixCSC, Am::Array, AoLjbmindices,
conjindicessorted, Ljb::SparseVector, Lmean)
Update the values in the sparse AoLjbm matrix in place.
JosephsonCircuits.valuetonumber
— Methodvaluetonumber(value, circuitdefs)
If the component value value
is a number (or a type we haven't considered, return it as is.
Examples
julia> JosephsonCircuits.valuetonumber(1.0,Dict(:Lj1=>1e-12,:Lj2=>2e-12))
1.0
JosephsonCircuits.valuetonumber
— Methodvaluetonumber(value::Complex{Symbolics.Num},circuitdefs)
If the component value value
is Complex{Symbolics.Num}, then try substituting in the definition from circuitdefs
.
Examples
julia> @variables Lj1::Complex;JosephsonCircuits.valuetonumber(Lj1,Dict(Lj1=>3.0e-12))
3.0e-12
julia> @variables Lj1::Complex Lj2::Complex;JosephsonCircuits.valuetonumber(Lj1+Lj2,Dict(Lj1=>3.0e-12,Lj2=>1.0e-12))
ComplexTerm(real(Lj2) + real(Lj1) + im*(imag(Lj2) + imag(Lj1)))
JosephsonCircuits.valuetonumber
— Methodvaluetonumber(value::Symbolics.Num,circuitdefs)
If the component value is Symbolics.Num, then try substituting in the definition from circuitdefs
.
Examples
julia> @variables Lj1;JosephsonCircuits.valuetonumber(Lj1,Dict(Lj1=>3.0e-12))
3.0e-12
julia> @variables Lj1 Lj2;JosephsonCircuits.valuetonumber(Lj1+Lj2,Dict(Lj1=>3.0e-12,Lj2=>1.0e-12))
4.0e-12
JosephsonCircuits.valuetonumber
— Methodvaluetonumber(value::String,circuitdefs)
If the component value is a string, assume it is a dictionary key.
Examples
julia> JosephsonCircuits.valuetonumber("Lj1",Dict("Lj1"=>1e-12,"Lj2"=>2e-12))
1.0e-12
JosephsonCircuits.valuetonumber
— Methodvaluetonumber(value::Symbol,circuitdefs)
If the component value is a symbol, assume it is a dictionary key.
Examples
julia> JosephsonCircuits.valuetonumber(:Lj1,Dict(:Lj1=>1e-12,:Lj2=>2e-12))
1.0e-12
JosephsonCircuits.valuetonumber
— Methodvaluetonumber(value::Symbolics.Symbol, circuitdefs)
If the component value value
has a type Complex{Symbolics.Num}, then try substituting in the definition from circuitdefs
.
Examples
julia> @syms Lj1;JosephsonCircuits.valuetonumber(Lj1,Dict(Lj1=>3.0e-12))
3.0e-12
julia> @syms Lj1 Lj2;JosephsonCircuits.valuetonumber(Lj1+Lj2,Dict(Lj1=>3.0e-12,Lj2=>1.0e-12))
4.0e-12
JosephsonCircuits.visualizefreqs
— Methodvisualizefreqs(w::NTuple{N,Any}, freq::Frequencies{N})
Create a vector or array containing the mixing products for visualization purposes.
Examples
@variables wp1
w = (wp1,)
freq = JosephsonCircuits.truncfreqs(
JosephsonCircuits.calcfreqsrdft((3,)),
dc=true, odd=true, even=true, maxintermodorder=Inf,
)
JosephsonCircuits.visualizefreqs(w,freq)
# output
4-element Vector{Num}:
0
wp1
2wp1
3wp1
@variables wp1,wp2
w = (wp1,wp2)
freq = JosephsonCircuits.truncfreqs(
JosephsonCircuits.calcfreqsrdft((3,3)),
dc=true, odd=true, even=true, maxintermodorder=3,
)
JosephsonCircuits.visualizefreqs(w,freq)
# output
4×7 Matrix{Num}:
0 wp2 2wp2 3wp2 -3wp2 -2wp2 -wp2
wp1 wp1 + wp2 wp1 + 2wp2 0 0 wp1 - 2wp2 wp1 - wp2
2wp1 2wp1 + wp2 0 0 0 0 2wp1 - wp2
3wp1 0 0 0 0 0 0
w = (1.1,1.2)
freq = JosephsonCircuits.truncfreqs(
JosephsonCircuits.calcfreqsrdft((3,3)),
dc=true, odd=true, even=true, maxintermodorder=3,
)
JosephsonCircuits.visualizefreqs(w,freq)
# output
4×7 Matrix{Float64}:
0.0 1.2 2.4 3.6 -3.6 -2.4 -1.2
1.1 2.3 3.5 0.0 0.0 -1.3 -0.1
2.2 3.4 0.0 0.0 0.0 0.0 1.0
3.3 0.0 0.0 0.0 0.0 0.0 0.0
JosephsonCircuits.wrspice_calcS_paramp
— Methodwrspice_calcS_paramp(out, wswrspice, Nnodes, stepsperperiod = 80,
Is = 1e-13)
This function assume the first node is the input port and the last node is the output port. Nnodes is the number of nodes including the ground node.
Examples
Nnodes = 2
ws = 2*pi*5e9
wp = 2*pi*6e9
stepsperperiod = 80
t = LinRange(0,2*pi/wp,stepsperperiod)
Is = 1e-13
Vpump = zeros(1,length(t))
Vsignalsin = zeros(1,length(t))
Vsignalcos = zeros(1,length(t))
Vpump[1,:] .= sin.(2*pi*wp*t)
Vsignalsin[1,:] .= sin.(2*pi*wp*t)+Is/50*sin.(2*pi*ws*t)
Vsignalcos[1,:] .= sin.(2*pi*wp*t)+Is/50*cos.(2*pi*ws*t)
out = [(values=Dict("S"=>t,"V"=>Vpump),),
(values=Dict("S"=>t,"V"=>Vsignalsin),),
(values=Dict("S"=>t,"V"=>Vsignalcos),),
];
out[1].values["V"];
out[2].values["V"];
out[3].values["V"];
JosephsonCircuits.wrspice_calcS_paramp(out, 2*pi, Nnodes;
stepsperperiod = stepsperperiod, Is = Is)
# output
(S11 = ComplexF64[-0.9999710828404902 + 2.7521387922213123e-5im], S21 = ComplexF64[2.8917159509832197e-5 + 2.7521387922213123e-5im])
JosephsonCircuits.wrspice_cmd
— Methodwrspice_cmd()
This returns the path of the WRSPICE executable.
JosephsonCircuits.wrspice_input_ac
— Methodwrspice_input_ac(netlist,nsteps,fstart,fstop)
Generate the WRSPICE input file for an AC small signal simulation using circuit parameters from the given netlist, and the specified frequency range. Example usage:
Examples
julia> println(JosephsonCircuits.wrspice_input_ac("* SPICE Simulation",100,4e9,5e9,[1,2],1e-6))
* SPICE Simulation
* AC current source with magnitude 1 and phase 0
isrc 1 0 ac 1.0e-6 0.0
* Set up the AC small signal simulation
.ac lin 100 4.0g 5.0g
* The control block
.control
* Maximum size of data to export in kilobytes from 1e3 to 2e9 with
* default 2.56e5. This has to come before the run command
set maxdata=2.0e9
* Run the simulation
run
* Binary files are faster to save and load.
set filetype=binary
* Leave filename empty so we can add that as a command line argument.
* Don't specify any variables so it saves everything.
write
.endc
julia> println(JosephsonCircuits.wrspice_input_ac("* SPICE Simulation",(4:0.01:5)*1e9,[1,2],1e-6))
* SPICE Simulation
* AC current source with magnitude 1 and phase 0
isrc 1 0 ac 1.0e-6 0.0
* Set up the AC small signal simulation
.ac lin 99 4.0g 5.0g
* The control block
.control
* Maximum size of data to export in kilobytes from 1e3 to 2e9 with
* default 2.56e5. This has to come before the run command
set maxdata=2.0e9
* Run the simulation
run
* Binary files are faster to save and load.
set filetype=binary
* Leave filename empty so we can add that as a command line argument.
* Don't specify any variables so it saves everything.
write
.endc
JosephsonCircuits.wrspice_input_paramp
— Methodwrspice_input_paramp(netlist, ws, wp, Ip; stepsperperiod = 80, Is = 1e-13,
tstop = 200e-9, trise = 10e-9)
Generate the WRSPICE input files for a time domain domain simulation in which the signal angular frequency is swept over ws
with pump angular frequency wp
and pump current Ip
.
Examples
using JosephsonCircuits
using Plots
circuit = [
("P1","1","0",1),
("R1","1","0",:R),
("C1","1","2",:Cc),
("Lj1","2","0",:Lj),
("C2","2","0",:Cj)]
circuitdefs = Dict(
:Lj =>1000.0e-12,
:Cc => 100.0e-15,
:Cj => 1000.0e-15,
:R => 50.0)
ws = 2*pi*(4.5:0.001:5.0)*1e9
wp = (2*pi*4.75001*1e9,)
Ip = 0.00565e-6
sources = [(mode=(1,),port=1,current=Ip)]
Npumpharmonics = (16,)
Nmodulationharmonics = (8,)
@time jpa = hbsolve(ws, wp, sources, Nmodulationharmonics,
Npumpharmonics, circuit, circuitdefs)
wswrspice=2*pi*(4.5:0.01:5.0)*1e9
n = JosephsonCircuits.exportnetlist(circuit,circuitdefs);
input = JosephsonCircuits.wrspice_input_paramp(n.netlist,wswrspice,wp[1],2*Ip);
@time output = JosephsonCircuits.spice_run(input,JosephsonCircuits.wrspice_cmd());
S11,S21=JosephsonCircuits.wrspice_calcS_paramp(output,wswrspice,n.Nnodes);
plot(ws/(2*pi*1e9),
10*log10.(abs2.(jpa.linearized.S((0,),1,(0,),1,:))),
label="JosephsonCircuits.jl",
xlabel="Frequency (GHz)",
ylabel="S11 (dB)")
plot!(wswrspice/(2*pi*1e9),10*log10.(abs2.(S11)),
label="WRSPICE",
seriestype=:scatter)
JosephsonCircuits.wrspice_input_transient
— Methodwrspice_input_transient(netlist::String, current, frequency, phase, tstep,
tstop, trise; maxdata = 2e9, jjaccel = 1, dphimax = 0.01,
filetype = "binary")
Generate the WRSPICE input file for a transient simulation using circuit parameters from the given netlist, the source current, frequency phase, and nodes for the sources, and the time step and stop time. Leave filename empty so we can add that as a command line argument. Don't specify any variables so it saves everything.
Arguments
netlist
: String containing the circuit netlist, excluding sources.current
: Vector of current source amplitudes in Ampere.frequency
: Vector of current source frequencies in Hz.phase
: Vector of current source phases in radians.sourcenodes
: Vector of tuples of nodes (src,dst) at which to place the current source(s).tstep
: Time step in seconds.tstop
: Time for which to run the simulation in seconds.trise
: The simulation ramps up the current source amplitude with a 1-sech(t/trise) envelope which reaches 35 percent of the peak in onetrise
.
Keywords
maxdata = 2e9
: Maximum size of data to export in kilobytes from 1e3 to 2e9 with WRspice default 2.56e5. This has to come before the run command.jjaccel = 1
: Causes a faster convergence testing and iteration control algorithm to be used, rather than the standard more comprehensive algorithm suitable for all devices.dphimax = 0.01
: The maximum allowed phase change per time step. Decreasing dphimax from the default of pi/5 to a smaller value is critical for matching the accuracy of the harmonic balance method simulations. This increases simulation time by pi/5/(dphimax).filetype = "binary" or "ascii"
: Binary files are faster to save and load.
Examples
julia> println(JosephsonCircuits.wrspice_input_transient("* SPICE Simulation",[1e-6,1e-3],[5e9,6e9],[3.14,6.28],[(1,0),(1,0)],1e-9,100e-9,10e-9))
* SPICE Simulation
* Current source
* 1-hyperbolic secant rise
isrc1 1 0 1.0u*cos(31.41592653589793g*x+3.14)*(1-2/(exp(x/1.0e-8)+exp(-x/1.0e-8)))
isrc2 1 0 1000.0u*cos(37.69911184307752g*x+6.28)*(1-2/(exp(x/1.0e-8)+exp(-x/1.0e-8)))
* Set up the transient simulation
* .tran 5p 10n
.tran 1000.0000000000001p 100.0n uic
* The control block
.control
set maxdata=2.0e9
set jjaccel=1
set dphimax=0.01
run
set filetype=binary
write
.endc