# Path: hftools/dataset/dim.py
# class _DimMatrix(DiagAxis):
#     sortprio = 1000
# 
# Path: hftools/dataset/arrayobj.py
# class hfarray(_hfarray):
#     def __new__(subtype, data, dims=None, dtype=None, copy=True, order=None,
#                 subok=False, ndmin=0, unit=None, outputformat=None, info=None):
#         if hasattr(data, "__hfarray__"):
#             data, dims = data.__hfarray__()
#             if unit is None and len(dims) == 1:
#                 unit = dims[0].unit
#             if outputformat is None and len(dims) == 1:
#                 outputformat = dims[0].outputformat
#         return _hfarray.__new__(subtype, data, dims=dims, dtype=dtype,
#                                 copy=copy, order=order, subok=subok,
#                                 ndmin=ndmin, unit=unit,
#                                 outputformat=outputformat, info=info)
# 
# def make_same_dims(A, B):
#     u"""Anropas med lista med *Arrays*. Returnerar arrayer som har samma *dims*
#     dvs vi har anropat change_shape med en *newinfo* som innehaller unionen
#     av de Axis objekt som finns i *dims* av *Arrayerna*.
# 
#     """
#     if not isinstance(B, _hfarray):
#         B = A.__class__(B.view(), dims=A.dims, copy=False)
#     return make_same_dims_list((A, B))
# 
# Path: hftools/math.py
# def det(A):
#     det = linalg.det
#     result = det(A)
#     result = hfarray(result, dims=A.dims[:-2])
#     return result
# 
# def inv(A):
#     inv = linalg.inv
#     result = inv(A)
#     result = hfarray(result, dims=A.dims)
#     return result
# 
# def matrix_multiply(a, b):
#     """Multiply arrays of matrices.
# 
#     a and b are hfarrays containing dimensions DimMatrix_i and DimMatrix_j.
#     Matrix multiplication is done by broadcasting the other dimensions first.
#     """
#     A, B = make_same_dims(a, b)
#     res = np.einsum("...ij,...jk->...ik", A, B)
#     return hfarray(res, dims=A.dims)


import numpy as np
from hftools.dataset import make_same_dims, _DimMatrix, hfarray
from hftools.math import det, inv, matrix_multiply
    X = X.reorder_dimensions(*neworder)
    e = e.reorder_dimensions(*neworder)
    klass, dims = X.__class__, X.dims
#    X, e = X.view(type=ndarray), X.view(type=ndarray)
    denom = (e[..., 0, 1] * e[..., 1, 0] -
             e[..., 0, 0] * e[..., 1, 1] +
             e[..., 1, 1] * X[..., 0, 0])
    maxshape = tuple(max(x) for x in zip(X.shape, e.shape))
    res = X.__class__(np.zeros(maxshape, X.dtype), dims=X.dims)
    e11 = (X[..., 0, 0] - e[..., 0, 0])
    e12 = (X[..., 0, 1] * e[..., 1, 0])
    e21 = (X[..., 1, 0] * e[..., 0, 1])
    e22 = (-X[..., 0, 1] * X[..., 1, 0] * e[..., 1, 1])
    res[..., 0, 0] = e11
    res[..., 0, 1] = e12
    res[..., 1, 0] = e21
    res[..., 1, 1] = e22
    res = res / denom
    res[..., 1, 1] = res[..., 1, 1] + X[..., 1, 1]
    res = klass(res, dims=dims)
    return res


def deembedright(X, e):
    """deembedright deembeds S-matrix e from S-matrix X from the right
    e, and S should all be on the four-matrix form:
    Frequency is first index, measurement sweep is second index and port
    indices are third and fourth index.
    """
    X, e = make_same_dims(X, e)

# Path: hftools/dataset/dim.py
# class _DimMatrix(DiagAxis):
#     sortprio = 1000
# 
# Path: hftools/dataset/arrayobj.py
# class hfarray(_hfarray):
#     def __new__(subtype, data, dims=None, dtype=None, copy=True, order=None,
#                 subok=False, ndmin=0, unit=None, outputformat=None, info=None):
#         if hasattr(data, "__hfarray__"):
#             data, dims = data.__hfarray__()
#             if unit is None and len(dims) == 1:
#                 unit = dims[0].unit
#             if outputformat is None and len(dims) == 1:
#                 outputformat = dims[0].outputformat
#         return _hfarray.__new__(subtype, data, dims=dims, dtype=dtype,
#                                 copy=copy, order=order, subok=subok,
#                                 ndmin=ndmin, unit=unit,
#                                 outputformat=outputformat, info=info)
# 
# def make_same_dims(A, B):
#     u"""Anropas med lista med *Arrays*. Returnerar arrayer som har samma *dims*
#     dvs vi har anropat change_shape med en *newinfo* som innehaller unionen
#     av de Axis objekt som finns i *dims* av *Arrayerna*.
# 
#     """
#     if not isinstance(B, _hfarray):
#         B = A.__class__(B.view(), dims=A.dims, copy=False)
#     return make_same_dims_list((A, B))
# 
# Path: hftools/math.py
# def det(A):
#     det = linalg.det
#     result = det(A)
#     result = hfarray(result, dims=A.dims[:-2])
#     return result
# 
# def inv(A):
#     inv = linalg.inv
#     result = inv(A)
#     result = hfarray(result, dims=A.dims)
#     return result
# 
# def matrix_multiply(a, b):
#     """Multiply arrays of matrices.
# 
#     a and b are hfarrays containing dimensions DimMatrix_i and DimMatrix_j.
#     Matrix multiplication is done by broadcasting the other dimensions first.
#     """
#     A, B = make_same_dims(a, b)
#     res = np.einsum("...ij,...jk->...ik", A, B)
#     return hfarray(res, dims=A.dims)


# Path: hftools/networks/spar_functions.py
import numpy as np
from hftools.dataset import make_same_dims, _DimMatrix, hfarray
from hftools.math import det, inv, matrix_multiply

    X = X.reorder_dimensions(*neworder)
    e = e.reorder_dimensions(*neworder)
    klass, dims = X.__class__, X.dims
#    X, e = X.view(type=ndarray), X.view(type=ndarray)
    denom = (e[..., 0, 1] * e[..., 1, 0] -
             e[..., 0, 0] * e[..., 1, 1] +
             e[..., 1, 1] * X[..., 0, 0])
    maxshape = tuple(max(x) for x in zip(X.shape, e.shape))
    res = X.__class__(np.zeros(maxshape, X.dtype), dims=X.dims)
    e11 = (X[..., 0, 0] - e[..., 0, 0])
    e12 = (X[..., 0, 1] * e[..., 1, 0])
    e21 = (X[..., 1, 0] * e[..., 0, 1])
    e22 = (-X[..., 0, 1] * X[..., 1, 0] * e[..., 1, 1])
    res[..., 0, 0] = e11
    res[..., 0, 1] = e12
    res[..., 1, 0] = e21
    res[..., 1, 1] = e22
    res = res / denom
    res[..., 1, 1] = res[..., 1, 1] + X[..., 1, 1]
    res = klass(res, dims=dims)
    return res


def deembedright(X, e):
    """deembedright deembeds S-matrix e from S-matrix X from the right
    e, and S should all be on the four-matrix form:
    Frequency is first index, measurement sweep is second index and port
    indices are third and fourth index.
    """
    X, e = make_same_dims(X, e)

    neworder = tuple([x for x in X.dims if not isinstance(x, _DimMatrix)])