Reference

JosephsonCircuits.Phi0Constant
const Phi0

A constant for Phi0, the magnetic flux quantum in Weber, HA: Phi0 = h/(2charge of electron).

JosephsonCircuits.phi0Constant
const phi0

A constant for phi0, the reduced magnetic flux quantum in Weber, HA: phi0 = hbar/(2charge of electron).

JosephsonCircuits.CircuitGraphType
CircuitGraph(edge2indexdict, Rbn, searray, cearray, glearray, lvarray,
    isolatednodes, gl, Nbranches)

A simple structure to hold the circuit graph information.

JosephsonCircuits.CircuitMatricesType
CircuitMatrices(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.FactorizationCacheType
FactorizationCache(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.FourierIndicesType
FourierIndices(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.FrequenciesType
Frequencies(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.HBType
HB(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. See NonlinearHB.
  • linearized: linearized harmonic balance solution. See LinearizedHB.
JosephsonCircuits.LinearizedHBType
LinearizedHB(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.NonlinearHBType
NonlinearHB(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 strings
  • portnumbers: 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.ParsedCircuitType
ParsedCircuit(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.ParsedSortedCircuitType
ParsedSortedCircuit(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.SpiceRawType
SpiceRaw(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.SpiceRawHeaderType
SpiceRawHeader(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.TouchstoneFileType
TouchstoneFile(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!Method
ABCD_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_PiYMethod
ABCD_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!Method
ABCD_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_TZMethod
ABCD_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!Method
ABCD_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_tlineMethod
ABCD_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!Method
ABCD_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_seriesZMethod
ABCD_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!Method
ABCD_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_shuntYMethod
ABCD_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!Method
ABCD_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_tlineMethod
ABCD_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.ABCDtoSFunction
ABCDtoS(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_tlinesMethod
A_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.AtoBFunction
AtoB(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.AtoSFunction
AtoS(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!Method
AtoS!(S::AbstractMatrix, A::AbstractMatrix, tmp::AbstractMatrix,
    sqrtportimpedances1, sqrtportimpedances2)

See AtoS for description.

JosephsonCircuits.AtoYFunction
AtoY(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.AtoZFunction
AtoZ(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.BtoAFunction
BtoA(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.BtoSFunction
BtoS(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!Method
BtoS!(S::AbstractMatrix, B::AbstractMatrix, tmp::AbstractMatrix,
    sqrtportimpedances1, sqrtportimpedances2)

See BtoS for description.

JosephsonCircuits.BtoYFunction
BtoY(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.BtoZFunction
BtoZ(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.CMtokeyedMethod
CMtokeyed(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.IctoLjMethod
IctoLj(Ic)

Convert the junction critical current to inductance in SI base units.

Examples

julia> IctoLj(3.29105976e-6)
1.0e-10
JosephsonCircuits.LjtoIcMethod
LjtoIc(Lj)

Convert the junction inductance to critical current in SI base units.

Examples

julia> LjtoIc(100e-12)
3.29105976e-6
JosephsonCircuits.S_match!Method
S_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!Method
S_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!Method
S_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!Method
S_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.SnoisetokeyedMethod
Snoisetokeyed(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.StoAFunction
StoA(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!Method
StoA!(A::AbstractMatrix, S::AbstractMatrix, tmp::AbstractMatrix,
    sqrtportimpedances1, sqrtportimpedances2)

See StoA for description.

JosephsonCircuits.StoABCDFunction
StoABCD(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.StoBFunction
StoB(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!Method
StoB!(B::AbstractMatrix, S::AbstractMatrix, tmp::AbstractMatrix,
    sqrtportimpedances1, sqrtportimpedances2)

See StoB for description.

JosephsonCircuits.StoTFunction
StoT(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.StoYFunction
StoY(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!Method
StoY!(Y::AbstractMatrix,S::AbstractMatrix,tmp::AbstractMatrix,sqrtportadmittances)

See StoY for description.

JosephsonCircuits.StoZFunction
StoZ(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!Method
StoZ!(Z::AbstractMatrix,S::AbstractMatrix,tmp::AbstractMatrix,sqrtportimpedances)

See StoZ for description.

JosephsonCircuits.StokeyedMethod
Stokeyed(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.StokeyedMethod
Stokeyed(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.TtoSFunction
TtoS(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.Y_PiY!Method
Y_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_PiYMethod
Y_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!Method
Y_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_seriesYMethod
Y_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.YtoAFunction
YtoA(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.YtoBFunction
YtoB(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.YtoSFunction
YtoS(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!Method
YtoS!(S::AbstractMatrix,Y::AbstractMatrix,tmp::AbstractMatrix,sqrtportimpedances)

See YtoS for description.

JosephsonCircuits.ZC_basis_coupled_tlinesMethod
ZC_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!Method
Z_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_TZMethod
Z_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_circuitsMethod
Z_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.

  1. low pass
   gnd--==========
1--> o--==========--o <--2
  1. band pass
   gnd--==========--o <--2
1--> o--==========--gnd
  1. band pass
        ==========--o <--2
1--> o--==========
  1. band pass
1--> o--==========--gnd
2--> o--==========
  1. all pass
        ==========
1--> o--==========--o  <--2
  1. all pass
   gnd--==========--gnd
1--> o--==========--o  <--2
  1. all pass
1--> o--==========--|
2--> o--==========--|
  1. all stop
   gnd--==========--o  <--2
1--> o--==========
  1. all stop
1--> o--==========--gnd
2--> o--==========--gnd
  1. 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!Method
Z_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_tlineMethod
Z_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!Method
Z_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_shuntZMethod
Z_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!Method
Z_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_tlineMethod
Z_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.ZtoAFunction
ZtoA(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.ZtoBFunction
ZtoB(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.ZtoSFunction
ZtoS(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!Method
ZtoS!(S::AbstractMatrix,Z::AbstractMatrix,tmp::AbstractMatrix,sqrtportimpedances)

See ZtoS for description.

JosephsonCircuits.add_portsMethod
add_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_splittersMethod
add_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_splittersMethod
add_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!Method
addsources!(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!Method
applynl!(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.applynlMethod
applynl(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.arraytonetworkdataMethod
arraytonetworkdata(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.calcAoLjbmMethod
calcAoLjbm(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.calcAoLjbm2Method
calcAoLjbm2(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.calcAoLjbmindicesMethod
calcAoLjbmindices(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.calcCjIcmeanMethod
calcCjIcmean(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.calcCnMethod
calcCn(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.calcGnMethod
calcGn(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.calcIbMethod
calcIb(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.calcLbMethod
calcLb(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.calcLjbMethod
calcLjb(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.calcLmeanMethod
calcLmean(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_innerMethod
calcLmean_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_innerMethod
calcLmean_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.calcMbMethod
calcMb(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.calcVbMethod
calcVb(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.calcbranchvectorMethod
calcbranchvector(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.calccircuitgraphMethod
calccircuitgraph(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!Method
calccm!(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!Method
calccm!(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!Method
calccm!(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!Method
calccm!(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.calccmMethod
calccm(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.calccmMethod
calccm(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.calcdZdroZ2Method
calcdZdroZ2(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!Method
calcfj!(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!Method
calcfj2!(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.calcfreqsMethod
calcfreqs(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.calcfreqsdftMethod
calcfreqsdft(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. See Frequencies.

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.calcfreqsrdftMethod
calcfreqsrdft(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. See Frequencies.

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.calcgraphsMethod
calcgraphs(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.calcimpedanceMethod
calcimpedance(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.calcimpedanceMethod
calcimpedance(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.calcindexdictMethod
calcindexdict(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.calcindexdictMethod
calcindexdict(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.calcindicesMethod
calcindices(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!Method
calcinputcurrentoutputvoltage!(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!Method
calcinputoutput!(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!Method
calcinputoutput_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!Method
calcinputoutputnoise!(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.calcinvLnMethod
calcinvLn(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.calcinvLnMethod
calcinvLn(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.calcmodefreqsMethod
calcmodefreqs(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.calcnodematrixMethod
calcnodematrix(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.calcnodesMethod
calcnodes(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.calcnodesortingMethod
calcnodesorting(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 in circuit.

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.calcnoiseportimpedanceindicesMethod
calcnoiseportimpedanceindices(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.calcphiindicesMethod
calcphiindices(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 domain
  • dropdict: 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 array
  • conjsourceindices: data should be copied from here
  • conjtargetindices: 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.calcportimpedanceindicesMethod
calcportimpedanceindices(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.calcportindicesnumbersMethod
calcportindicesnumbers(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!Method
calcqe!(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!Method
calcqe!(qe, S)

Calculate the quantum efficiency matrix for a scattering matrix in the field ladder operator basis. Overwrites qe with output.

JosephsonCircuits.calcqeMethod
calcqe(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.calcqeMethod
calcqe(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.calcqeidealMethod
calcqeideal(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!Method
calcscatteringmatrix!(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!Method
calcscatteringmatrix!(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!Method
calcscatteringmatrix!(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.calcsourcesMethod
calcsources(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.calcspicesortpermsMethod
calcspicesortperms(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.calcvaluetypeMethod
calcvaluetype(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!Method
calcw!(ws, i, wp, w)

Generate the signal and idler frequencies using the formula ws + 2iwp. Overwrites w with output.

JosephsonCircuits.calcwMethod
calcw(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.cascadeSMethod
cascadeS(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.checkcomponenttypesMethod
checkcomponenttypes(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.checkissymbolicMethod
checkissymbolic(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.checkissymbolicMethod
checkissymbolic(a::Num)

Check if a is a symbolic variable.

Examples

julia> @variables w;JosephsonCircuits.checkissymbolic(w)
true
JosephsonCircuits.comparearrayMethod
comparearray(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.comparestructMethod
comparestruct(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.componentdictionariesMethod
componentdictionaries(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.componentvaluestonumberMethod
componentvaluestonumber(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!Method
conjnegfreq!(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.conjnegfreqMethod
conjnegfreq(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.conjsymMethod
conjsym(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!Method
connectS!(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.connectSMethod
connectS(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.connectSMethod
connectS(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.connectSMethod
connectS(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_initializeMethod
connectS_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_initializeMethod
connectS_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.connectSportsMethod
connectSports(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.connectSportsMethod
connectSports(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!Method
diagrepeat!(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.diagrepeatMethod
diagrepeat(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.diagrepeatMethod
diagrepeat(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.diagrepeatMethod
diagrepeat(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.diagrepeatMethod
diagrepeat(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.edge2indexMethod
edge2index(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_maxwellMethod
even_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_mutualMethod
even_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!Method
export_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.exportnetlistMethod
exportnetlist(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!Method
extractbranches!(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.extractbranchesMethod
extractbranches(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_connectionsMethod
find_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_namesMethod
find_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.findgroundnodeindexMethod
findgroundnodeindex(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.freqsubstMethod
freqsubst(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.frequencyscaleMethod
frequencyscale(frequencyunit::String)

Convert the SI prefix in the string frequencyunit to the corresponding numerical value.

Examples

julia> JosephsonCircuits.frequencyscale("MHz")
1.0e6
JosephsonCircuits.get_portsMethod
get_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_portsMethod
get_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.hblinsolveMethod
hblinsolve(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. See LinearizedHB.

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.hblinsolveMethod
hblinsolve(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!Method
hblinsolve_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.hblinsolveoldMethod
hblinsolveold(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 to nothing by default but should be set equal to the frequency variable like w 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. See sortnodes for other options if this fails.
  • returnS = true: if true, return the scattering parameters for each set of ports and signal and idler frequencies.
  • returnSnoise = false: if true, 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: if true, return the quantum efficiency for each signal and idler at each combinaton of ports.
  • returnCM = true: if true, return the commutation relations for each signal and idler at each combinaton of ports (should equal ±1).
  • returnnodeflux = false: if true, return the node fluxes for each signal and idler at each node. Set to false by default to reduce memory usage.
  • returnnodefluxadjoint = false: if true, return the node fluxes adjoint for each signal and idler at each node. Set to false by default to reduce memory usage.
  • returnvoltage = false: if true, return the node voltages for each signal and idler at each node. Set to false 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.hbmatindMethod
hbmatind(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.hbmatindMethod
hbmatind(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.hbnlsolveMethod
hbnlsolve(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.hbnlsolveMethod
hbnlsolve(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. See NonlinearHB.

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.hbnlsolveoldMethod
hbnlsolveold(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 of Ip must be equal to length of ports.
  • 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 to nothing by default but should be set equal to the frequency variable like w if there is frequency dependence.
  • sorting = :number: sort the ports by turning them into integers and sorting those integers. See sortnodes 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.hbsolveMethod
hbsolve(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.hbsolveMethod
hbsolve(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. See HB.
JosephsonCircuits.hbsolveoldMethod
hbsolveold(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 of Ip must be equal to length of pumpports.
  • 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 to nothing by default but should be set equal to the frequency variable like w 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. See sortnodes for other options if this fails.
  • returnS = true: if true, return the scattering parameters for each set of ports and signal and idler frequencies.
  • returnSnoise = false: if true, 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: if true, return the quantum efficiency for each signal and idler at each combinaton of ports.
  • returnCM = true: if true, return the commutation relations for each signal and idler at each combinaton of ports (should equal ±1).
  • returnnodeflux = false: if true, return the node fluxes for each signal and idler at each node. Set to false by default to reduce memory usage.
  • returnnodefluxadjoint = false: if true, return the node fluxes adjoint for each signal and idler at each node. Set to false by default to reduce memory usage.
  • returnvoltage = false: if true, return the node voltages for each signal and idler at each node. Set to false 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!Method
import_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_netlistMethod
import_netlist(filename)

Import the netlist from the IOBuffer or IOStream io and return a vector of tuples representing the circuit.

JosephsonCircuits.isbegininformationMethod
isbegininformation(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.isendMethod
isend(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.isendinformationMethod
isendinformation(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.ismatrixformatMethod
ismatrixformat(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.ismixedmodeorderMethod
ismixedmodeorder(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.isnetworkdataMethod
isnetworkdata(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.isnoisedataMethod
isnoisedata(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.isnumberoffrequenciesMethod
isnumberoffrequencies(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.isnumberofnoisefrequenciesMethod
isnumberofnoisefrequencies(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.isnumberofportsMethod
isnumberofports(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.isoptionlineMethod
isoptionline(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.isreferenceMethod
isreference(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.istwoportdataorderMethod
istwoportdataorder(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.isversionMethod
isversion(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.keepfreqsMethod
keepfreqs(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.keepfreqsMethod
keepfreqs(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_2x2Method
ldiv_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.linesearchMethod
linesearch(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_2x2Method
lu_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!Method
make_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.matrixindicesMethod
matrixindices(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.matrixindicesMethod
matrixindices(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_combineMethod
maxwell_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_oddMethod
maxwell_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_mutualMethod
maxwell_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!Method
move_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!Method
move_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!Method
move_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!Method
move_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!Method
move_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_oddMethod
mutual_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_maxwellMethod
maxwell_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.networkdatatoarrayMethod
networkdatatoarray(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!Method
nlsolve!(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.nodevariabletokeyedMethod
nodevariabletokeyed(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.nodevariabletokeyedMethod
nodevariabletokeyed(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.numericmatricesMethod
numericmatrices(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_sparseMethod
parse_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.parsecircuitMethod
parsecircuit(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.parsecomponenttypeMethod
parsecomponenttype(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!Method
parseinformation!(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.parsematrixformatMethod
parsematrixformat(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!Method
parsemixedmodeorder!(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!Method
parsenetworkdata!(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!Method
parsenoisedata!(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.parsenumberoffrequenciesMethod
parsenumberoffrequencies(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.parsenumberofnoisefrequenciesMethod
parsenumberofnoisefrequencies(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.parsenumberofportsMethod
parsenumberofports(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.parseoptionlineMethod
parseoptionline(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!Method
parsereference!(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.parsesortcircuitMethod
parsesortcircuit(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 in circuit.

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.parsespicevariableMethod
parsespicevariable(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.parsetwoportdataorderMethod
parsetwoportdataorder(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.parseversionMethod
parseversion(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!Method
phimatrixtovector!(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!Method
phivectortomatrix!(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_rowsMethod
pivot_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_rowsMethod
pivot_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_applynlMethod
plan_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.printsymmetriesMethod
printsymmetries(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.printsymmetriesMethod
printsymmetries(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.processnodeMethod
processnode(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.processnodeMethod
processnode(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!Method
pushval!(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!Method
remove_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.removeconjfreqsMethod
removeconjfreqs(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.removefreqsMethod
removefreqs(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.removefreqsMethod
removefreqs(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.showstructMethod
showstruct(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.sincosnlMethod
sincosnl(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.sincosnloddtobothMethod
sincosnloddtoboth(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!Method
solveS!(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.solveSMethod
solveS(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!Method
solveS_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.sortnodesMethod
sortnodes(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.spaddkeepzerosMethod
spaddkeepzeros(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!Method
sparseadd!(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!Method
sparseadd!(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!Method
sparseadd!(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!Method
sparseadd!(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!Method
sparseaddconjsubst!(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.sparseaddmapMethod
sparseaddmap(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_raw_loadMethod
spice_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_runMethod
spice_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_runMethod
spice_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!Method
spmatmul!(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.sprandsubsetFunction
sprandsubset(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!Method
storeuniqueloops!(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!Method
stripcommentslowercase!(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!Method
sumbranchvalues!(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.sumvaluesMethod
sumvalues(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.symbolicindicesMethod
symbolicindices(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.symbolicmatricesMethod
symbolicmatrices(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.testshowMethod
testshow(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_fileMethod
touchstone_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_loadMethod
touchstone_load(filename)

Read a file in the Touchstone format. Standard compliant.

References to the 1.1 spec and the 2.0 spec.

Outputs un-normalized network parameters with frequency units of Hz. Don't enforce any particular file extension or try to infer the number of ports from the extension.

JosephsonCircuits.touchstone_parseMethod
touchstone_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_saveMethod
touchstone_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.

References to the 1.1 spec and the 2.0 spec.

JosephsonCircuits.touchstone_writeMethod
touchstone_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_writeMethod
touchstone_write(io::IO, ts::TouchstoneFile)

Write a Touchstone file specified by the TouchstoneFile object ts to the IOStream or IOBuffer io.

JosephsonCircuits.truncfreqsMethod
truncfreqs(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!Method
tryfactorize!(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!Method
trysolve!(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.tuple2edgeMethod
tuple2edge(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.tuple2edgeMethod
tuple2edge(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.tuple2edgeMethod
tuple2edge(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.tuple2edgeMethod
tuple2edge(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!Method
updateAoLjbm!(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!Method
updateAoLjbm2!(AoLjbm::SparseMatrixCSC, Am::Array, AoLjbmindices,
    conjindicessorted, Ljb::SparseVector, Lmean)

Update the values in the sparse AoLjbm matrix in place.

JosephsonCircuits.valuetonumberMethod
valuetonumber(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.valuetonumberMethod
valuetonumber(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.valuetonumberMethod
valuetonumber(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.valuetonumberMethod
valuetonumber(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.valuetonumberMethod
valuetonumber(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.valuetonumberMethod
valuetonumber(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.visualizefreqsMethod
visualizefreqs(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_parampMethod
wrspice_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_input_acMethod
wrspice_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_parampMethod
wrspice_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_transientMethod
wrspice_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 one trise.

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