# -*- coding: utf-8 -*-
# =============================================================================
#  Copyright (C) 2018 Mercados Electricos de Centroamérica. All rights reserved
# =============================================================================

"""
Construye las matrices B para el cálculo de flujos DC
"""

from numpy import ones, r_, zeros
from scipy.sparse import csr_matrix as sparse
from utils.idx_brch import BUS_I, BUS_J, X


def makeBdc(bus, branch):
    """Construye las matrices B para el cálculo de flujos DC.

    Se construye primer la matriz de incidencia Cft (o matriz A, como se    denomina en la formulación de substas de
    Derechos Firmes) y se define como:

    El valor será uno (1) para las líneas ij donde su nodo inicial sea igual al nodo i y menos uno (-1) para las lineas
    ij cuyo nodo final sea igual al nodo j.

    La matriz de incidencias Cft tiene dimenciones C{nbr x nb}, en donde C{nbr}es el numero de líneas (branches) y
    C{nb} el número de buses.

    Luego se calcula la matriz Bf (ZZ) de dimensiones C{nbr x nb}, en donde C{nbr} es el numero de líneas (branches) y
    C{nb} el número de buses, igual que la Matriz de Incidencias.

    Contiene los mismos elementos nulos que la matriz Cft y cuyas componentes no nulas son:

        1. Para la componente correspondiente a la fila de cada circuito br,y cuya columna corresponde al nodo de
        llegada del circuito b

            :math:`Bf[br,b] = 1/Xbr`

        2. Para la componente correspondiente a la fila de cada circuito br, y cuya columna corresponde al nodo de
        salida del circuito b

            :math:`Bf[br,b] = -1/Xbr`

    La matriz Bbus se calcula como la transpuesta de la matriz de incidencias Cft por la matriz Bf

        :math:`Bbus = Cft.T * Bf`

    .. codeauthor:: Oscar A. Leiva (MERELEC)
    """
    # constantes
    nb = bus.shape[0]
    nbr = branch.shape[0]

    # construye la matriz de incidencia Cft
    f = branch[:, BUS_I].astype(float)          # lista de buses de origen
    t = branch[:, BUS_J].astype(float)          # lista de buses de destino
    i = r_[range(nbr), range(nbr)]             # Set doble de indices de filas

    # Matriz de incidencia
    Cft = sparse((r_[ones(nbr), -ones(nbr)], (i, r_[f, t])), (nbr, nb))

    #print(Cft)
    return Cft
