pyGM: Factor Objects

class Factor

Factors are the basic building block of our graphical model representations. In general, a factor consists of a set of variables (its “scope”), and the function values f(x) for each joint configuration x (a tuple of values) of its variables. Factors support basic operations common in probabilistic inference, including artihmetic operations, marginalization, optimization, and sampling.

Constructor & Accessors

Factor.__init__(vars={}, vals=1.0)[source]

Constructor for Factor class

>>> f = Factor( [X,Y,Z],[vals] )     # creates factor over [X,Y,Z] with table [vals] 

[vals] should be a correctly sized numpy array, or something that can be cast to the same.

pyGM.Factor.vars = <property object>

Variables (scope) of the factor; read-only

pyGM.Factor.table = <property object>

Table (values, as numpy array) of the factor

pyGM.Factor.nvar = <property object>

Number of arguments (variables, scope size) for the factor

Factor.numel()[source]

Number of elements (size) of the tabular factor

Factor.dims()[source]

Dimensions (table shape) of the tabular factor

Factor.__getitem__(loc)[source]

Accessor: F[x1,x2] = F[sub2ind(x1,x2)] = F(X1=x1,X2=x2)

Factor.valueMap(x)[source]

Accessor: F[x[i],x[j]] where i,j = F.vars, i.e, x is a map from variables to their state values

Factor.__setitem__(loc, val)[source]

Assign values of the factor: F[i,j,k] = F[idx] = val if idx=sub2ind(i,j,k)

Factor.__float__()[source]

Convert factor F to scalar float if possible; otherwise raises ValueError

Factor.__str__()[source]

Basic string representation: scope (varset) only

Factor.__repr__()[source]

Detailed representation: scope (varset) + table memory location

Factor.copy()[source]

Copy constructor; make a copy of a factor

Factor.changeVars(vars, copy=True)[source]

Copy a factor but change its arguments (scope).

>>> f = Factor([X0,X1], table)      
>>> g = changeVars( f, [X7,X5])   # now,  g(X5=b,X7=a) = f(X0=a,X1=b)

Unary Math Operators

These methods perform element-wise mathematical transformations to the factor:

Factor.__abs__()[source]

Return the absolute value of F: G = F.abs() => G(x) = | F(x) | for all x

Factor.__neg__()[source]

Return the negative of F: G = -F => G(x) = -F(x) for all x

Factor.exp()[source]

Return the exponential of F: G = F.exp() => G(x) = exp(F(x)) for all x

Factor.log()[source]

Return the natural log of F: G = F.log() => G(x) = log( F(x) ) for all x

Factor.log10()[source]

Return the log base 10 of F: G = F.log10() => G(x) = log10( F(x) ) for all x

Factor.log2()[source]

Return the log base 2 of F: G = F.log2() => G(x) = log2( F(x) ) for all x

There are also in-place versions:

Factor.absIP()[source]

Take the absolute value of F: F.absIP() => F(x) <- |F(x)| (in-place)

Factor.expIP()[source]

Take the exponential of F: F.expIP() => F(x) <- exp(F(x)) (in-place)

Factor.logIP()[source]

Take the natural log of F: F.logIP() => F(x) <- log( F(x) ) (in-place)

Factor.log10IP()[source]

Take the log base 10 of F: F.log10IP() => F(x) <- log10( F(x) ) (in-place)

Factor.log2IP()[source]

Take the log base 2 of F: F.log2IP() => F(x) <- log2( F(x) ) (in-place)

Binary Math Operators

These methods provide arithmetic operations that combine two factors into a single factor over the union of their scope:

Factor.__add__(that)[source]

Addition of factors, e.g., G(x_1,x_2) = F1(x_1) + F2(x_2)

Factor.__sub__(that)[source]

Subtraction of factors, e.g., G(x_1,x_2) = F1(x_1) - F2(x_2)

Factor.__mul__(that)[source]

Multiplication of factors, e.g., G(x_1,x_2) = F1(x_1) * F2(x_2)

Factor.__div__(that)[source]

Division of factors, e.g., G(x_1,x_2) = F1(x_1) / F2(x_2)

Factor.__pow__(power)[source]

Return F raised to a power: G = F.power(p) => G(x) = ( F(x) )^p for all x

There are also in-place versions:

Factor.__iadd__(that)[source]

In-place addition, F1 += F2. Most efficient if F2.vars <= F1.vars

Factor.__isub__(that)[source]

In-place subtraction, F1 -= F2. Most efficient if F2.vars <= F1.vars

Factor.__imul__(that)[source]

In-place multiplication, F1 *= F2. Most efficient if F2.vars <= F1.vars

Factor.__idiv__(that)[source]

In-place divide, F1 /= F2. Most efficient if F2.vars <= F1.vars

Factor.__ipow__(power)

Raise F to a power: F.powerIP(p) => F(x) <- ( F(x) )^p (in-place)

Elimination and Conditioning

These methods produce a smaller factor, defined over fewer variables, by either eliminating over or conditioning on a subset of the arguments.

Factor.sum(elim=None, out=None)[source]

Eliminate via sum on F, e.g., f(X_2) = sum_{x_1} F(x_1,X_2) = F.sum([X1])

Factor.max(elim=None, out=None)[source]

Eliminate via max on F, e.g., f(X_2) = max_{x_1} F(x_1,X_2) = F.max([X1])

Factor.min(elim=None, out=None)[source]

Eliminate via min on F, e.g., f(X_2) = min_{x_1} F(x_1,X_2) = F.min([X1])

Factor.lse(elim=None, out=None)[source]

Eliminate via log-sum-exp on F, e.g., f(X_2) = log sum_{x_1} exp F(x_1,X_2) = F.lse([X1])

Factor.sumPower(elim=None, power=1.0, out=None)[source]

Eliminate via powered sum, e.g., f(X_2) = root^{1/p}{ sum_{x_1} F(x_1,X_2)^p } = F.sumPower([X1],p)

Factor.lsePower(elim=None, power=1.0, out=None)[source]

Eliminate via powered log-sum-exp, e.g., f(X_2) = 1/p log sum_{x_1} exp F(x_1,X_2)*p = F.lsePower([X_1],p)

Factor.marginal(target, out=None)[source]

Compute the marginal of F, e.g., f(X_2) = sum_{x_1} F(x_1,X_2) = F.marginal([X2])

Factor.maxmarginal(target, out=None)[source]

Compute the max-marginal of F, e.g., f(X_2) = max_{x_1} F(x_1,X_2) = F.maxmarginal([X2])

Factor.minmarginal(target, out=None)[source]

Compute the min-marginal of F, e.g., f(X_2) = min_{x_1} F(x_1,X_2) = F.minmarginal([X2])

Factor.condition(evidence)[source]

Create a clamped (or “sliced”) factor using partial conditioning (dict version)

>>> F.condition({0:a,2:b})   # returns  f(X_1,X_3) = F(X_0=a, X_1, X_2=b, X_3)
Factor.condition2(cvars=[], ctuple=[])[source]

Create a clamped (or “sliced”) factor using partial conditioning (list+list version)

>>> F.condition2([0,2],[a,b])   # returns  f(X_1,X_3) = F(X_0=a, X_1, X_2=b, X_3)

Tuple / Configuration Methods

These methods return a tuple of integers, corresponding to some configuration of the factor’s arguments:

Factor.argmax(evidence={})[source]

Find the argmax of the factor, with partial conditioning (as dict evidence[v]) if desired

Returns a maximizing configuration of f(X|Xc=xc) as a tuple of states

Factor.argmin(evidence={})[source]

Find the argmin of the factor, with partial conditioning if desired (dict version)

Factor.argmax2(cvars=None, ctuple=None)[source]

Find the argmax of the factor, with partial conditioning (as var list + value list) if desired.

Returns a maximizing configuration of f(X|Xc=xc) as a tuple of states

Factor.argmin2(cvars=None, ctuple=None)[source]

Find the argmin of the factor, with partial conditioning if desired (list+list version)

Factor.sample(Z=None)[source]

Draw a random sample (as a tuple of states) from the factor; assumes positivity.

If option Z=<float> set, the function will assume normalization factor Z

Boolean Tests

Factor.isfinite()[source]

Check for infinite (-inf, inf) or NaN values in the factor; false if any present

Factor.isnan()[source]

Check for NaN (not-a-number) entries in the factor’s values; true if any NaN present

Factor.isAny(test)[source]

Generic check for any entries satisfying lambda-expression “test” in the factor

Other

Factor.entropy()[source]

Compute the entropy of the factor (normalizes, assumes positive)

Factor.distance(that, distance)[source]

Compute any of several norm-like functions on F(x).

‘distance’ can be any of:
‘L1’ : L1 or manhattan distance, sum of absolute values ‘L2’ : L2 or Euclidean distance, sum of squares ‘LInf’ : L-Infinity distance, maximum value ‘KL’ : Shannon entropy (KL = Kullback Leibler) ‘HPM’ : Hilbert’s projective metric