Skip to content

Instantly share code, notes, and snippets.

@emaxerrno
Created September 20, 2013 03:10
Show Gist options
  • Select an option

  • Save emaxerrno/6632852 to your computer and use it in GitHub Desktop.

Select an option

Save emaxerrno/6632852 to your computer and use it in GitHub Desktop.
coursera pmg: FactorProduct.m
% FactorProduct Computes the product of two factors.
% C = FactorProduct(A,B) computes the product between two factors, A and B,
% where each factor is defined over a set of variables with given dimension.
% The factor data structure has the following fields:
% .var Vector of variables in the factor, e.g. [1 2 3]
% .card Vector of cardinalities corresponding to .var, e.g. [2 2 2]
% .val Value table of size prod(.card)
%
% See also FactorMarginalization.m, IndexToAssignment.m, and
% AssignmentToIndex.m
function C = FactorProduct(A, B)
% Check for empty factors
if (isempty(A.var)), C = B; return; end;
if (isempty(B.var)), C = A; return; end;
% Check that variables in both A and B have the same cardinality
[dummy iA iB] = intersect(A.var, B.var);
if ~isempty(dummy)
% A and B have at least 1 variable in common
assert(all(A.card(iA) == B.card(iB)), 'Dimensionality mismatch in factors');
end
% Set the variables of C
C.var = union(A.var, B.var);
% Construct the mapping between variables in A and B and variables in C.
% In the code below, we have that
%
% mapA(i) = j, if and only if, A.var(i) == C.var(j)
%
% and similarly
%
% mapB(i) = j, if and only if, B.var(i) == C.var(j)
%
% For example, if A.var = [3 1 4], B.var = [4 5], and C.var = [1 3 4 5],
% then, mapA = [2 1 3] and mapB = [3 4]; mapA(1) = 2 because A.var(1) = 3
% and C.var(2) = 3, so A.var(1) == C.var(2).
[dummy, mapA] = ismember(A.var, C.var);
[dummy, mapB] = ismember(B.var, C.var);
% Set the cardinality of variables in C
C.card = zeros(1, length(C.var));
C.card(mapA) = A.card;
C.card(mapB) = B.card;
% Initialize the factor values of C:
% prod(C.card) is the number of entries in C
C.val = zeros(1, prod(C.card));
% Compute some helper indices
% These will be very useful for calculating C.val
% so make sure you understand what these lines are doing.
assignments = IndexToAssignment(1:prod(C.card), C.card);
indxA = AssignmentToIndex(assignments(:, mapA), A.card);
indxB = AssignmentToIndex(assignments(:, mapB), B.card);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% YOUR CODE HERE:
% Correctly populate the factor values of C
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Factor product means : say A has to rand vars x1,x2 and B has 2 rand vars x2 and x3
% factor product would be a='x1 * x2'; you can look this up
% multiplied by b='x2 * x3' you also look this up.
% final result is a * b
% and you store it in x1,x2,x3 entry
% make sure that we fill up all of the elements in the val
for i = 1:length(C.val)
a = A.val(indxA(i));
b = B.val(indxB(i));
%get any index for A
C.val(i) = b * a;
endfor
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment