Ejemplo n.º 1
0
def factor_sum(A, B):
    """Same as factor_product, but sums instead of multiplies
    """
    if A.is_empty():
        return B
    if B.is_empty():
        return A

    # Create output factor. Variables should be the union between of the
    # variables contained in the two input factors
    out = Factor()
    out.var = np.union1d(A.var, B.var)

    # Compute mapping between the variable ordering between the two factors
    # and the output to set the cardinality
    out.card = np.zeros(len(out.var), np.int64)
    mapA = np.argmax(out.var[None, :] == A.var[:, None], axis=-1)
    mapB = np.argmax(out.var[None, :] == B.var[:, None], axis=-1)
    out.card[mapA] = A.card
    out.card[mapB] = B.card

    # For each assignment in the output, compute which row of the input factors
    # it comes from
    out.val = np.zeros(np.prod(out.card))
    assignments = out.get_all_assignments()
    idxA = assignment_to_index(assignments[:, mapA], A.card)
    idxB = assignment_to_index(assignments[:, mapB], B.card)
    """ YOUR CODE HERE
    You should populate the .val field with the factor sum. The code for this
    should be very similar to the factor_product().
    """
    out.val = A.val[idxA] + B.val[idxB]

    return out
Ejemplo n.º 2
0
def factor_marginalize(factor, var):
    """
    Returns factor after variables in var have been marginalized out.
    Args:
        factor: factor to be marginalized
        var: numpy array of variables to be marginalized over
    Returns:
        marginalized factor
    """
    out = copy.deepcopy(factor)
    """ YOUR CODE HERE
     HINT: Use the code from lab1 """
    out.var = np.setdiff1d(factor.var, var)
    map_out = np.argmax(out.var[:, None] == factor.var[None, :], axis=-1)
    out.card = factor.card[map_out]
    out.val = np.zeros(np.prod(out.card))

    assignments_in = index_to_assignment(np.arange(int(np.prod(factor.card))),
                                         factor.card)
    idx_out = assignment_to_index(assignments_in[:, map_out], out.card)

    for i in range(out.val.shape[0]):
        out.val[i] = np.sum(factor.val[idx_out == i])
    """ END YOUR CODE HERE """
    return out
Ejemplo n.º 3
0
def factor_marginalize(factor, var):
    """Sums over a list of variables.

    Args:
        factor (Factor): Input factor
        var (List): Variables to marginalize out

    Returns:
        out: Factor with variables in 'var' marginalized out.
    """
    out = Factor()
    """ YOUR CODE HERE
    Marginalize out the variables given in var
    """

    out.var = np.setxor1d(factor.var, np.array(var))

    for out_var in out.var:
        index = np.where(factor.var == out_var)
        out.card = np.append(out.card, factor.card[index])

    assignment = factor.get_all_assignments()
    index = []
    for single_var in var:
        index.append(np.where(factor.var == single_var))

    assignment = np.delete(assignment, index, axis=1)

    out.val = np.zeros(np.prod(out.card))
    for i in np.unique(assignment, axis=0):
        index_set = np.array(np.where(np.all(i == assignment, axis=1)))
        single_assignment = assignment_to_index(i, out.card)
        out.val[single_assignment] = np.sum(factor.val[index_set])
    return out
Ejemplo n.º 4
0
def factor_product(A, B):
    """Compute product of two factors.

    Suppose A = phi(X_1, X_2), B = phi(X_2, X_3), the function should return
    phi(X_1, X_2, X_3)
    """
    if A.is_empty():
        return B
    if B.is_empty():
        return A

    # Create output factor. Variables should be the union between of the
    # variables contained in the two input factors
    out = Factor()
    out.var = np.union1d(A.var, B.var)

    # Compute mapping between the variable ordering between the two factors
    # and the output to set the cardinality
    out.card = np.zeros(len(out.var), np.int64)
    mapA = np.argmax(out.var[None, :] == A.var[:, None], axis=-1)
    mapB = np.argmax(out.var[None, :] == B.var[:, None], axis=-1)
    out.card[mapA] = A.card
    out.card[mapB] = B.card

    # For each assignment in the output, compute which row of the input factors
    # it comes from
    out.val = np.zeros(np.prod(out.card))
    assignments = out.get_all_assignments()
    idxA = assignment_to_index(assignments[:, mapA], A.card)
    idxB = assignment_to_index(assignments[:, mapB], B.card)

    out.val = A.val[idxA] * B.val[idxB]
    """ YOUR CODE HERE
    You should populate the .val field with the factor product
    Hint: The code for this function should be very short (~1 line). Try to
      understand what the above lines are doing, in order to implement
      subsequent parts.
    """
    return out
Ejemplo n.º 5
0
def factor_product(A, B):
    """
    Computes the factor product of A and B e.g. A = f(x1, x2); B = f(x1, x3); out=f(x1, x2, x3) = f(x1, x2)f(x1, x3)
    Args:
        A: first Factor
        B: second Factor
    Returns:
        Returns the factor product of A and B
    """
    out = Factor()
    """ YOUR CODE HERE,     HINT: copy from lab2 part 1! """
    if A.is_empty():
        return B
    if B.is_empty():
        return A

    out = Factor()

    # Set the variables of the output
    out.var = np.union1d(A.var, B.var)

    # Set the cardinality of the output
    out.card = np.zeros(len(out.var), np.int64)
    mapA = np.argmax(out.var[None, :] == A.var[:, None], axis=-1)
    mapB = np.argmax(out.var[None, :] == B.var[:, None], axis=-1)
    out.card[mapA] = A.card
    out.card[mapB] = B.card

    # Initialize the factor values to zero
    out.val = np.zeros(np.prod(out.card))
    assignments = out.get_all_assignments()
    idxA = assignment_to_index(assignments[:, mapA], A.card)
    idxB = assignment_to_index(assignments[:, mapB], B.card)

    # Populate the factor values
    out.val = A.val[idxA] * B.val[idxB]
    """ END YOUR CODE HERE """
    return out
Ejemplo n.º 6
0
def factor_max_marginalize(factor, var):
    """Marginalize over a list of variables by taking the max.

    Args:
        factor (Factor): Input factor
        var (List): Variable to marginalize out.

    Returns:
        out: Factor with variables in 'var' marginalized out. The factor's
          .val_argmax field should be a list of dictionary that keep track
          of the maximizing values of the marginalized variables.
          e.g. when out.val_argmax[i][j] = k, this means that
            when assignments of out is index_to_assignment[i],
            variable j has a maximizing value of k.
          See test_lab1.py::test_factor_max_marginalize() for an example.
    """
    out = Factor()
    """ YOUR CODE HERE
    Marginalize out the variables given in var. 
    You should make use of val_argmax to keep track of the location with the
    maximum probability.
    """
    out.var = np.setxor1d(factor.var, np.array(var))

    for out_var in out.var:
        index = np.where(factor.var == out_var)
        out.card = np.append(out.card, factor.card[index])

    assignment = factor.get_all_assignments()
    index = []
    out.val_argmax = []
    for single_var in var:
        index.append(np.where(factor.var == single_var))

    delete_assignment = np.delete(assignment, index, axis=1)

    out.val = np.zeros(np.prod(out.card))
    for i in np.unique(delete_assignment, axis=0):
        index_set = np.array(np.where(np.all(i == delete_assignment, axis=1)))
        index_set_max_index = np.argmax(factor.val[index_set])
        max_index_assignment = index_set[:, index_set_max_index][0]
        single_assignment = assignment_to_index(i, out.card)
        out.val[single_assignment] = factor.val[max_index_assignment]
        temp_dict = {}
        for single_var in var:
            index = np.argwhere(factor.var == single_var)[0][0]
            temp_dict[single_var] = assignment[max_index_assignment][index]
        out.val_argmax.append(temp_dict)
    return out