/******************************************************************************* * Copyright 2013 Analog Devices, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ********************************************************************************/ package com.analog.lyric.dimple.factorfunctions; import static com.analog.lyric.math.Utilities.*; import com.analog.lyric.dimple.exceptions.DimpleException; import com.analog.lyric.dimple.factorfunctions.core.FactorFunction; import com.analog.lyric.dimple.model.values.Value; /** * Parameterized discrete transition factor, which corresponds to p(y | x, A), * where A is a matrix of transition probabilities that are * parameterized as *unnormalized* probabilities. * The transition matrix is organized such that columns correspond to * the output distribution for each input state. That is, the transition * matrix multiplies on the left. The domain of x and y do not need to be * the same. * <p> * Representing A as described, the conjugate prior for A is such that * each entry of the A matrix is independently distributed according to * a Gamma distribution, all with a common Beta parameter. * Depending on the solver, it may or may not be necessary to use a * conjugate prior (for the Gibbs solver, for example, it is not). * <p> * The variables in the argument list are ordered as follows: * <ol> * <li>y: Discrete output variable * <li>x: Discrete input variable * <li>...: The entries of the transition matrix flattened out in column major order (the standard * multidimensional array order used by MATLAB). * </ol> */ public class DiscreteTransitionUnnormalizedParameters extends FactorFunction { /*------- * State */ private final static int NUM_DATA_ARGUMENTS = 2; protected final int _yDimension; protected final int _xDimension; /*-------------- * Construction */ public DiscreteTransitionUnnormalizedParameters(int dimension) {this(dimension, dimension);} // Square transition matrix public DiscreteTransitionUnnormalizedParameters(int yDimension, int xDimension) { super(); _yDimension = yDimension; _xDimension = xDimension; } /*------------------------ * FactorFunction methods */ @Override public final double evalEnergy(Value[] arguments) { if (arguments.length != _xDimension*_yDimension + NUM_DATA_ARGUMENTS) throw new DimpleException("Incorrect number of arguments."); final int y = arguments[0].getIndexOrInt(); // First argument is y (output variable) final int x = arguments[1].getIndexOrInt(); // Second argument is x (input variable) // Beginning of the column for the given value of x (matrix is scanned by columns) final int colStartIndex = x * _yDimension + NUM_DATA_ARGUMENTS; double sum = 0; for (int index = colStartIndex + _yDimension; --index>=colStartIndex;) { final double a = arguments[index].getDouble(); if (a < 0) return Double.POSITIVE_INFINITY; sum += a; } return weightToEnergy(arguments[colStartIndex + y].getDouble()) + Math.log(sum); } // Factor-specific methods public final int getXDimension() { return _xDimension; } public final int getYDimension() { return _yDimension; } public final int getNumParameters() { return _xDimension * _yDimension; } }