001/* A line coder, which converts a sequence of booleans into symbols. 002 003 Copyright (c) 1998-2014 The Regents of the University of California. 004 All rights reserved. 005 Permission is hereby granted, without written agreement and without 006 license or royalty fees, to use, copy, modify, and distribute this 007 software and its documentation for any purpose, provided that the above 008 copyright notice and the following two paragraphs appear in all copies 009 of this software. 010 011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 015 SUCH DAMAGE. 016 017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 022 ENHANCEMENTS, OR MODIFICATIONS. 023 024 PT_COPYRIGHT_VERSION_2 025 COPYRIGHTENDKEY 026 027 */ 028package ptolemy.domains.sdf.lib; 029 030import ptolemy.data.ArrayToken; 031import ptolemy.data.BooleanToken; 032import ptolemy.data.IntToken; 033import ptolemy.data.Token; 034import ptolemy.data.expr.Parameter; 035import ptolemy.data.type.ArrayType; 036import ptolemy.data.type.BaseType; 037import ptolemy.kernel.CompositeEntity; 038import ptolemy.kernel.util.IllegalActionException; 039import ptolemy.kernel.util.InternalErrorException; 040import ptolemy.kernel.util.NameDuplicationException; 041import ptolemy.kernel.util.Workspace; 042 043/////////////////////////////////////////////////////////////////// 044//// LineCoder 045 046/** 047 A line coder, which converts a sequence of booleans into symbols. 048 049 @author Edward A. Lee, Steve Neuendorffer 050 @version $Id$ 051 @since Ptolemy II 0.2 052 @Pt.ProposedRating Green (eal) 053 @Pt.AcceptedRating Yellow (cxh) 054 */ 055public class LineCoder extends SDFTransformer { 056 /** Construct an actor with the given container and name. 057 * @param container The container. 058 * @param name The name of this actor. 059 * @exception IllegalActionException If the actor cannot be contained 060 * by the proposed container. 061 * @exception NameDuplicationException If the container already has an 062 * actor with this name. 063 */ 064 public LineCoder(CompositeEntity container, String name) 065 throws NameDuplicationException, IllegalActionException { 066 super(container, name); 067 068 input.setTypeEquals(BaseType.BOOLEAN); 069 070 table = new Parameter(this, "table"); 071 table.setExpression("{-1.0, 1.0}"); 072 attributeChanged(table); 073 074 wordLength = new Parameter(this, "wordLength", new IntToken(1)); 075 wordLength.setTypeEquals(BaseType.INT); 076 077 // Type constraints. 078 output.setTypeAtLeast(ArrayType.elementType(table)); 079 } 080 081 /////////////////////////////////////////////////////////////////// 082 //// public variables //// 083 084 /** The code table. Its value is a token of type ArrayToken. 085 * The array provides the symbol values to produce on the output. 086 * The number of values in this array must be at least 087 * 2<sup><i>wordLength</i></sup>, or an exception 088 * will be thrown. The number of tokens consumed by this actor when 089 * it fires is log<sub>2</sub>(<i>tableSize</i>), where 090 * <i>tableSize</i> is the length of the table. If all of these 091 * values are <i>false</i>, then the first array entry is produced 092 * as an output. If only the first one is true, then then second 093 * array value is produced. In general, the <i>N</i> inputs consumed 094 * are taken to be a binary digit that indexes the array, 095 * where the first input is taken to be the low-order bit of the array. 096 * The default code table has two entries, -1.0 097 * and 1.0, so that input <i>false</i> values are mapped to -1.0, 098 * and input <i>true</i> values are mapped to +1.0. 099 */ 100 public Parameter table; 101 102 /** The word length is the number of boolean inputs that are consumed 103 * to construct an index into the table. Its value is an IntToken, 104 * with default value one. 105 */ 106 public Parameter wordLength; 107 108 /////////////////////////////////////////////////////////////////// 109 //// public methods //// 110 111 /** Clone the actor into the specified workspace. This calls the 112 * base class and then resets the type constraints. 113 * @param workspace The workspace for the new object. 114 * @return A new actor. 115 * @exception CloneNotSupportedException If a derived class contains 116 * an attribute that cannot be cloned. 117 */ 118 @Override 119 public Object clone(Workspace workspace) throws CloneNotSupportedException { 120 LineCoder newObject = (LineCoder) super.clone(workspace); 121 122 // set the type constraints 123 try { 124 newObject.output 125 .setTypeAtLeast(ArrayType.elementType(newObject.table)); 126 } catch (IllegalActionException e) { 127 throw new InternalErrorException(e); 128 } 129 130 return newObject; 131 } 132 133 /** Consume the inputs and produce the corresponding symbol. 134 * @exception IllegalActionException If a runtime type error occurs. 135 */ 136 @Override 137 public void fire() throws IllegalActionException { 138 super.fire(); 139 140 int tableAddress = 0; 141 Token[] tokens = input.get(0, _wordLength); 142 143 for (int i = 0; i < _wordLength; i++) { 144 boolean data = ((BooleanToken) tokens[i]).booleanValue(); 145 146 if (data) { 147 tableAddress |= 1 << i; 148 } 149 } 150 151 output.send(0, _table[tableAddress]); 152 } 153 154 /** Set up the consumption constant. 155 * @exception IllegalActionException If the length of the table is not 156 * a power of two. 157 */ 158 @Override 159 public void preinitialize() throws IllegalActionException { 160 super.preinitialize(); 161 162 _wordLength = ((IntToken) wordLength.getToken()).intValue(); 163 164 // Set the token consumption rate. 165 input_tokenConsumptionRate.setToken(new IntToken(_wordLength)); 166 167 ArrayToken tableToken = (ArrayToken) table.getToken(); 168 int size = (int) Math.pow(2, _wordLength); 169 170 if (tableToken.length() < size) { 171 throw new IllegalActionException(this, 172 "Table parameter must " + "have at least " + size 173 + " entries, but only has " + tableToken.length()); 174 } 175 176 _table = tableToken.arrayValue(); 177 } 178 179 /////////////////////////////////////////////////////////////////// 180 //// private variables //// 181 // Local cache of these parameter values. 182 private int _wordLength; 183 184 private Token[] _table; 185}