import numpy as np

from .CurveParam import CurveParam
from .Curve import Curve

class LogCurve(Curve):
    def __init__(self):
        super().__init__()
        self.offset = CurveParam("offset")
        self.offset.min_bound = 1.00001
        self.offset.initial = 2.0
        self.scale = CurveParam("scale")

    __mime_type__ = "application/x-insarviz/LogCurve"

    @property
    def nparams(self):
        return 2
    @property
    def params(self):
        return [self.scale, self.offset]

    def func(self, xs, scale, offset):
        return scale * np.log(xs + offset)
    def jacobian(self, xs, scale, offset):
        offset_xs = xs + offset
        return np.array([np.log(offset_xs), scale / offset_xs])
    def hessian_epsilon(self, xs, err, grad, scale, offset):
        offset_xs = xs + offset

        d_scale_scale    = 0
        d_scale_offset   = np.sum(err / offset_xs)
        d_offset_offset  = - scale * np.sum(err / (offset_xs * offset_xs))

        hessian = np.array([
            [ d_scale_scale, d_scale_offset ],
            [ d_scale_offset, d_offset_offset]
        ])

        return np.dot(hessian @ grad, grad)
