def tn_cdf(x, intervals, mean=0, var=1):
  """
  CDF of a truncated normal distribution

  [Parameters]
    x <float> : Return the value at x
    intervals <list np.ndarray> : [L, U] or [[L1, U1], [L2, U2],...]
    mean <float>
    var <float>

  [Returns]
    float : CDF of TN
  """
  intervals = np.array(intervals)

  if len(intervals.shape) == 1:
    intervals = np.array([intervals,])

  n_intervals = len(intervals)  # number of intervals
  sd = math.sqrt(var)  # standard deviation

  # locate the interval that contains x
  for i in range(n_intervals):
    if intervals[i][0] <= x <= intervals[i][1]:
      x_index = i
      break
  else:
    # raise ValueError(f'tn_cdf at x={x} is undefined.\nintervals={intervals}')
    raise ValueError("error! x:", x, ", intervals:", intervals)

  norm_intervals = (intervals - mean) / sd  # normalized intervals

  # calculate the sum(delta) in order
  delta = [0,]
  for i in range(n_intervals):
    diff = mp.ncdf(norm_intervals[i][1]) - mp.ncdf(norm_intervals[i][0])
    delta.append(delta[-1] + diff)

  numerator = mp.ncdf((x-mean)/sd) - mp.ncdf(norm_intervals[x_index][0]) + delta[x_index]
  denominator = delta[-1]

  return float(numerator / denominator)
Exemple #2
0
def norm_interval(lower, upper):
    r"""
    A multiprecision evaluation of

    .. math::

        \Phi(U) - \Phi(L)

    Parameters
    ----------

    lower : float
        The lower limit $L$

    upper : float
        The upper limit $U$

    """
    if lower > 0 and upper > 0:
        return mp.ncdf(-lower) - mp.ncdf(-upper)
    else:
        return mp.ncdf(upper) - mp.ncdf(lower)
def pivot(A, bh, list_active_set, list_zk, list_bhz, etaj, etajTy, cov, tn_mu, type):

    tn_sigma = np.sqrt(np.dot(np.dot(etaj.T, cov), etaj))[0][0]

    z_interval = []

    for i in range(len(list_active_set)):
        if type == 'As':
            if np.array_equal(np.sign(bh), np.sign(list_bhz[i])):
                z_interval.append([list_zk[i], list_zk[i + 1] - 1e-10])

        if type == 'A':
            if np.array_equal(A, list_active_set[i]):
                z_interval.append([list_zk[i], list_zk[i + 1] - 1e-10])

    new_z_interval = []

    for each_interval in z_interval:
        if len(new_z_interval) == 0:
            new_z_interval.append(each_interval)
        else:
            sub = each_interval[0] - new_z_interval[-1][1]
            if abs(sub) < 0.01:
                new_z_interval[-1][1] = each_interval[1]
            else:
                new_z_interval.append(each_interval)

    z_interval = new_z_interval

    numerator = 0
    denominator = 0

    for each_interval in z_interval:
        al = each_interval[0]
        ar = each_interval[1]

        denominator = denominator + mp.ncdf((ar - tn_mu)/tn_sigma) - mp.ncdf((al - tn_mu)/tn_sigma)

        if etajTy >= ar:
            numerator = numerator + mp.ncdf((ar - tn_mu)/tn_sigma) - mp.ncdf((al - tn_mu)/tn_sigma)
        elif (etajTy >= al) and (etajTy < ar):
            numerator = numerator + mp.ncdf((etajTy - tn_mu)/tn_sigma) - mp.ncdf((al - tn_mu)/tn_sigma)

    if denominator != 0:
        return float(numerator/denominator)
    else:
        return None
Exemple #4
0
def truncnorm_cdf(observed, lower, upper):
    r"""
    Compute the truncated normal 
    distribution function.

    .. math::

        \frac{\Phi(U) - \Phi(T)}{\Phi(U) - \Phi(L)}

    where $T$ is `observed`, $L$ is `lower_bound` and $U$ is `upper_bound`.

    Parameters
    ----------

    observed : float

    lower : float

    upper : float

    Returns
    -------

    P : float

    """
    x, a, b = observed, lower, upper

    x = max(x, a)
    x = min(x, b)

    #a = max(min(a, 5), -5)
    #b = max(min(b, 5), -5)
    #x = max(min(x, 5), -5)
    #if a==b:
    #    return 1.

    if a > 0 and b > 0:
        Fx, Fa, Fb = mp.ncdf(-x), mp.ncdf(-a), mp.ncdf(-b)
        return float((Fa - Fx) / (Fa - Fb))
    else:
        Fx, Fa, Fb = mp.ncdf(x), mp.ncdf(a), mp.ncdf(b)
        return float((Fx - Fa) / (Fb - Fa))
def pivot_with_specified_interval(z_interval, etaj, etajTy, cov, tn_mu):

    tn_sigma = np.sqrt(np.dot(np.dot(etaj.T, cov), etaj))[0][0]

    numerator = 0
    denominator = 0

    for each_interval in z_interval:
        al = each_interval[0]
        ar = each_interval[1]

        denominator = denominator + mp.ncdf((ar - tn_mu)/tn_sigma) - mp.ncdf((al - tn_mu)/tn_sigma)

        if etajTy >= ar:
            numerator = numerator + mp.ncdf((ar - tn_mu)/tn_sigma) - mp.ncdf((al - tn_mu)/tn_sigma)
        elif (etajTy >= al) and (etajTy < ar):
            numerator = numerator + mp.ncdf((etajTy - tn_mu)/tn_sigma) - mp.ncdf((al - tn_mu)/tn_sigma)

    if denominator != 0:
        return float(numerator/denominator)
    else:
        return None
def f(z_interval, etajTy, mu, tn_sigma):
    numerator = 0
    denominator = 0

    for each_interval in z_interval:
        al = each_interval[0]
        ar = each_interval[1]

        denominator = denominator + mp.ncdf((ar - mu) / tn_sigma) - mp.ncdf(
            (al - mu) / tn_sigma)

        if etajTy >= ar:
            numerator = numerator + mp.ncdf((ar - mu) / tn_sigma) - mp.ncdf(
                (al - mu) / tn_sigma)
        elif (etajTy >= al) and (etajTy < ar):
            numerator = numerator + mp.ncdf(
                (etajTy - mu) / tn_sigma) - mp.ncdf((al - mu) / tn_sigma)

    if denominator != 0:
        return float(numerator / denominator)
    else:
        return np.Inf
def truncnorm_cdf(observed, lower, upper):
    r"""
    Compute the truncated normal 
    distribution function.

    .. math::

        \frac{\Phi(U) - \Phi(T)}{\Phi(U) - \Phi(L)}

    where $T$ is `observed`, $L$ is `lower_bound` and $U$ is `upper_bound`.

    Parameters
    ----------

    observed : float

    lower : float

    upper : float

    Returns
    -------

    P : float

    """
    x, a, b = observed, lower, upper

    x = max(x, a)
    x = min(x, b)

    if a > 0 and b > 0:
        Fx, Fa, Fb = mp.ncdf(-x), mp.ncdf(-a), mp.ncdf(-b)
        return float( ( Fa - Fx ) / ( Fa - Fb ) )
    else:
        Fx, Fa, Fb = mp.ncdf(x), mp.ncdf(a), mp.ncdf(b)
        return float( ( Fx - Fa ) / ( Fb - Fa ) )
def inference(data, segment_index, global_list_conditioning_matrix, sigma,
              first_segment_index, second_segment_index):
    x = np.array(data)
    n = len(x)
    x = x.reshape((x.shape[0], 1))

    vector_1_C_a = np.zeros(n)
    vector_1_C_b = np.zeros(n)

    n_a = 0
    n_b = 0

    for i in range(n):
        if segment_index[i] == second_segment_index:
            n_a = n_a + 1
            vector_1_C_a[i] = 1.0

        elif segment_index[i] == first_segment_index:
            n_b = n_b + 1
            vector_1_C_b[i] = 1.0

    vector_1_C_a = np.reshape(vector_1_C_a, (vector_1_C_a.shape[0], 1))
    vector_1_C_b = np.reshape(vector_1_C_b, (vector_1_C_b.shape[0], 1))

    first_element = np.dot(vector_1_C_a.T, x)[0][0]
    second_element = np.dot(vector_1_C_b.T, x)[0][0]

    tau = first_element / n_a - second_element / n_b

    if tau < 0:
        temp = vector_1_C_a
        vector_1_C_a = vector_1_C_b
        vector_1_C_b = temp

        temp = n_a
        n_a = n_b
        n_b = temp

    first_element = np.dot(vector_1_C_a.T, x)[0][0]
    second_element = np.dot(vector_1_C_b.T, x)[0][0]

    tau = first_element / n_a - second_element / n_b

    big_sigma = sigma * sigma * np.identity(n)

    eta_a_b = vector_1_C_a / n_a - vector_1_C_b / n_b

    c_vector = np.dot(big_sigma, eta_a_b) / (
        (np.dot(eta_a_b.T, np.dot(big_sigma, eta_a_b)))[0][0])

    z = np.dot((np.identity(n) - np.dot(c_vector, eta_a_b.T)), x)

    L_prime = np.NINF
    U_prime = np.Inf

    L_tilde = np.NINF
    U_tilde = np.Inf

    list_2_range = []
    range_tau_greater_than_zero = [0, np.Inf]

    for matrix in global_list_conditioning_matrix:
        c_T_A_c = np.dot(c_vector.T, np.dot(matrix, c_vector))[0][0]
        z_T_A_c = np.dot(z.T, np.dot(matrix, c_vector))[0][0]
        c_T_A_z = np.dot(c_vector.T, np.dot(matrix, z))[0][0]
        z_T_A_z = np.dot(z.T, np.dot(matrix, z))[0][0]

        a = c_T_A_c
        b = z_T_A_c + c_T_A_z
        c = z_T_A_z

        if -error_threshold <= a <= error_threshold:
            a = 0

        if -error_threshold <= b <= error_threshold:
            b = 0

        if -error_threshold <= c <= error_threshold:
            c = 0

        x_T_A_x = np.dot(x.T, np.dot(matrix, x))[0][0]
        x_T_A_c = np.dot(x.T, np.dot(matrix, c_vector))[0][0]
        c_T_A_x = np.dot(c_vector.T, np.dot(matrix, x))[0][0]

        if a == 0:
            if b == 0:
                if c > 0:
                    print('z_T_A_z > 0')
            elif b < 0:
                temporal_lower_bound = -c / b
                L_prime = max(L_prime, temporal_lower_bound)

                if L_prime > tau:
                    print('L_prime > tau')
            elif b > 0:
                temporal_upper_bound = -c / b
                U_prime = min(U_prime, temporal_upper_bound)

                if U_prime < tau:
                    print('U_prime < tau')
        else:
            delta = b**2 - 4 * a * c
            check_delta = (x_T_A_c + c_T_A_x)**2 - 4 * c_T_A_c * x_T_A_x

            if abs(delta - check_delta) > 1e-8:
                print('delta - check_delta')

            if -error_threshold <= delta <= error_threshold:
                delta = 0

            if delta == 0:
                if a > 0:
                    print('c_T_A_c > 0 and delta = 0')
            elif delta < 0:
                if a > 0:
                    print('c_T_A_c > 0 and delta < 0')
            elif delta > 0:
                if a > 0:
                    x_lower = (-b - np.sqrt(delta)) / (2 * a)
                    x_upper = (-b + np.sqrt(delta)) / (2 * a)

                    if x_lower > x_upper:
                        print('x_lower > x_upper')

                    L_tilde = max(L_tilde, x_lower)
                    U_tilde = min(U_tilde, x_upper)

                else:
                    x_1 = (-b - np.sqrt(delta)) / (2 * a)
                    x_2 = (-b + np.sqrt(delta)) / (2 * a)

                    x_low = min(x_1, x_2)
                    x_up = max(x_1, x_2)
                    list_2_range.append([x_low, x_up])

    final_list_range = intersect_range([L_prime, U_prime], [L_tilde, U_tilde],
                                       range_tau_greater_than_zero,
                                       list_2_range)

    if len(final_list_range) == 0:
        print('NO SOLUTION')
        return None

    numerator = 0
    denominator = 0

    tn_sigma = np.sqrt(np.dot(eta_a_b.T, np.dot(big_sigma, eta_a_b))[0][0])

    for each_final_range in final_list_range:
        al = each_final_range[0]
        ar = each_final_range[1]

        denominator = denominator + (mp.ncdf(ar / tn_sigma) -
                                     mp.ncdf(al / tn_sigma))
        if tau >= ar:
            numerator = numerator + (mp.ncdf(ar / tn_sigma) -
                                     mp.ncdf(al / tn_sigma))
        elif (tau >= al) and (tau < ar):
            numerator = numerator + (mp.ncdf(tau / tn_sigma) -
                                     mp.ncdf(al / tn_sigma))

    if denominator != 0:
        F = numerator / denominator
        return 1 - F
    else:
        print('denominator = 0', final_list_range, tau, tn_sigma)
        return None
def Phi(x):
    return( mp.ncdf(x) )
Exemple #10
0
def inference(opt_funct_set, opt_funct, eta_vec, eta_T_x, cov, n):
    # big_sigma = sigma * sigma * np.identity(n)
    tn_sigma = np.sqrt(np.dot(eta_vec.T, np.dot(cov, eta_vec))[0][0])
    list_interval = []

    for k, func_cost in opt_funct_set.items():
        a = func_cost[0] - opt_funct[0]
        b = func_cost[1] - opt_funct[1]
        c = func_cost[2] - opt_funct[2]

        a = check_zero(a)
        b = check_zero(b)
        c = check_zero(c)

        if (a == 0) and (b != 0):
            print('a == 0 and b != 0')

        if a == 0:
            continue

        # c = c - cost

        x_1, x_2 = quadratic_solver(a, b, c)
        if (x_1 is None) and (x_2 is None):
            if a < 0:
                print('negative a')
            continue

        elif x_1 == x_2:
            if a > 0:
                list_interval.append([np.NINF, x_1])
            elif a < 0:
                list_interval.append([x_2, np.Inf])

        else:
            if a > 0:
                list_interval.append([x_1, x_2])
            elif a < 0:
                list_interval.append([np.NINF, x_1])
                list_interval.append([x_2, np.Inf])

    sorted_list_interval = sorted(list_interval)

    union_interval = [sorted_list_interval[0]]
    for element in sorted_list_interval:
        no_of_ranges, returned_interval = union(union_interval[-1], element)
        if no_of_ranges == 2:
            union_interval[-1] = returned_interval[0]
            union_interval.append(returned_interval[1])
        else:
            union_interval[-1] = returned_interval

    z_interval = [[np.NINF, union_interval[0][0]]]

    for i in range(len(union_interval) - 1):
        z_interval.append([union_interval[i][1], union_interval[i + 1][0]])

    z_interval.append([union_interval[-1][1], np.Inf])

    # print(z_interval)

    negative_eta = - abs(eta_T_x)
    positive_eta = abs(eta_T_x)

    numerator_1 = 0
    numerator_2 = 0
    denominator = 0

    for each_interval in z_interval:
        al = each_interval[0]
        ar = each_interval[1]

        denominator = denominator + (mp.ncdf(ar / tn_sigma) - mp.ncdf(al / tn_sigma))

        if negative_eta >= ar:
            numerator_1 = numerator_1 + (mp.ncdf(ar / tn_sigma) - mp.ncdf(al / tn_sigma))
        elif (negative_eta >= al) and (negative_eta < ar):
            numerator_1 = numerator_1 + (mp.ncdf(negative_eta / tn_sigma) - mp.ncdf(al / tn_sigma))

        if positive_eta >= ar:
            numerator_2 = numerator_2 + (mp.ncdf(ar / tn_sigma) - mp.ncdf(al / tn_sigma))
        elif (positive_eta >= al) and (positive_eta < ar):
            numerator_2 = numerator_2 + (mp.ncdf(positive_eta / tn_sigma) - mp.ncdf(al / tn_sigma))

    if denominator != 0:
        p_value = numerator_1 / denominator + (1 - numerator_2 / denominator)
        return float(p_value)
    else:
        return None