/******************************************************************************* * Copyright 2012 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.solvers.sumproduct; import java.util.HashMap; import com.analog.lyric.dimple.exceptions.DimpleException; import com.analog.lyric.dimple.model.domains.FiniteFieldDomain; import com.analog.lyric.dimple.model.variables.Discrete; import com.analog.lyric.dimple.solvers.interfaces.ISolverFactorGraph; /** * Solver variable for FiniteField variable under Sum-Product solver. * <p> * This class provides an implementation for FiniteField variables (with a characteristic of 2). * It does not modify * the update algorithm but provides dlog and power tables for the FiniteField function classes. * The dlog (discrete log) table can be used for calculating the discrete log of the variable. * The power table does the opposite. * * There is a unique pair of lookup tables for each primitive polynomial. As a result we cache * the lookup tables for each unique primitive polynomial. * * @since 0.07 */ @SuppressWarnings("deprecation") // TODO remove when SDiscreteVariable removed public class SumProductFiniteFieldVariable extends SDiscreteVariable { //global cache of lookup tables. private static HashMap<Integer,LookupTables> _poly2tables = new HashMap<Integer,LookupTables>(); //A pointer to the correct lookup table for this variable. private final LookupTables _tables; private final int _numBits; public SumProductFiniteFieldVariable(Discrete var, ISolverFactorGraph parent) { super(var, parent); final FiniteFieldDomain domain = (FiniteFieldDomain)var.getDomain(); int key = domain.getPrimitivePolynomial(); _numBits = domain.getN(); //Create the tables if they don't exist. if (!_poly2tables.containsKey(key)) _poly2tables.put(key,new LookupTables(key, _numBits)); //save the tables. _tables = _poly2tables.get(key); } public LookupTables getTables() { return _tables; } public int getNumBits() { return _numBits; } /** * The LookupTables class simply contains the polynomial and the dlog and power tables. * * @since 0.07 */ public class LookupTables { private int _poly; private int [] _powerTable; private int [] _dlogTable; //The constructor constructs the tables. public LookupTables(int poly, int polySize) { _poly = poly; //Num entries is 2^polySize-1 int numEntries = (1 << polySize)-1; _powerTable = new int [numEntries]; _dlogTable = new int [numEntries+1]; _dlogTable[0] = -1; //Really this is undefined _powerTable[0] = 1; int current = _powerTable[0]; //Calculate the powers using the LFSR of the primite polynomial for (int i = 1; i < numEntries; i++) { //LFSR equation current = ((current >> (polySize-1))*_poly ^ (current << 1)) & numEntries; //If we get back to 1 before ending the sequence, this is not a primitive //polynomial. if (current == 1) throw new DimpleException("polynomial is not irreducible"); //Store the entry in the tables. _dlogTable[current] = i; _powerTable[i] = current; } } public int [] getPowerTable() { return _powerTable; } public int [] getDlogTable() { return _dlogTable; } //Useful for debug public void prettyPrint(int current,int polySize) { for (int j = 0; j < polySize+1;j++) { if ((current & (1 << (polySize-j))) != 0) { System.out.print("1"); } else System.out.print("0"); } System.out.print("\n"); } public int getPoly() { return _poly; } } }