#!/usr/bin/env python
# -*- coding: utf-8 -*-
# time: 2023/5/8 13:15
# file: loss.py.py
# author: David
# company: shenyang JY
import tensorflow as tf
from keras import backend as K
import keras


class SouthLoss(keras.losses.Loss):
    def __init__(self, cap, units=None):
        """
        南网新规则损失函数
        :param cap:装机容量
        """
        super().__init__()
        self.cap = 0.2 * cap

    def call(self, y_true, y_predict):
        """
        自动调用
        :param y_true: 标签
        :param y_predict: 预测
        :return: 损失值
        """
        # 计算实际和预测的差值
        diff = y_true - y_predict
        # y_true 减去 0.2cap，再乘以1000，y_true所有低于0.2cap的为高负值，高于0.2cap为高正值
        # 再sigmoid函数，对于高正值，此函数为1，对于高负值，此函数为0
        logistic_values = tf.sigmoid(1000 * (y_true - self.cap))
        # logistic_values，遮罩了所有负值，1-logistic_values，遮罩了所有正值
        # 遮罩负值，正值保留原有差值，遮罩正值，负值用0.2cap替换负值
        base = logistic_values * diff + (1-logistic_values)*self.cap
        loss = K.square(diff/base)
        loss = K.mean(loss, axis=-1)
        return loss