001/* An binary, orthogonal communication system.
002
003Copyright (c) 1998-2014 The Regents of the University of California.
004All rights reserved.
005
006Permission is hereby granted, without written agreement and without
007license or royalty fees, to use, copy, modify, and distribute this
008software and its documentation for any purpose, provided that the above
009copyright notice and the following two paragraphs appear in all copies
010of this software.
011
012IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
013FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
014ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
015THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
016SUCH DAMAGE.
017
018THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
019INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
020MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
021PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
022CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
023ENHANCEMENTS, OR MODIFICATIONS.
024
025                                        PT_COPYRIGHT_VERSION_2
026                                        COPYRIGHTENDKEY
027 */
028
029package ptolemy.domains.sdf.demo.OrthogonalCom;
030
031import ptolemy.actor.TypedCompositeActor;
032import ptolemy.actor.TypedIORelation;
033import ptolemy.actor.lib.AddSubtract;
034import ptolemy.actor.lib.Const;
035import ptolemy.actor.lib.DiscreteRandomSource;
036import ptolemy.actor.lib.Gaussian;
037import ptolemy.actor.lib.Maximum;
038import ptolemy.actor.lib.Multiplexor;
039import ptolemy.actor.lib.io.ExpressionWriter;
040import ptolemy.data.DoubleToken;
041import ptolemy.data.IntToken;
042import ptolemy.data.type.BaseType;
043import ptolemy.domains.sdf.kernel.SDFDirector;
044import ptolemy.domains.sdf.lib.DotProduct;
045import ptolemy.domains.sdf.lib.SequenceToArray;
046import ptolemy.kernel.util.IllegalActionException;
047import ptolemy.kernel.util.NameDuplicationException;
048import ptolemy.kernel.util.Workspace;
049
050/**
051An binary, orthogonal communication system. Randomly choose a bit,
052send the signal associated with the bit, add Gaussian noise to
053the signal, and attempt to recover the bit using the maximum
054likelihood decision rule. The difference between the send and output
055bit is output on the screen. (0 = no error; 1,-1 = error).
056
057This class is used as a demonstration of the codegen facility, which is
058why it is written in Java instead of using MoML.
059
060@author Jeff Tsay
061@version $Id$
062@since Ptolemy II 8.0
063@version $Id$
064@Pt.ProposedRating Red (ctsay)
065@Pt.AcceptedRating Red (ctsay)
066 */
067public class OrthogonalCom extends TypedCompositeActor {
068
069    /** Construct the orthogonal communication system.
070     *  @param w The workspace in which to construct the system.
071     *  @exception IllegalActionException If the system cannot be
072     *  constructed.
073     */
074    public OrthogonalCom(Workspace w) throws IllegalActionException {
075        super(w);
076
077        try {
078            setDirector(new SDFDirector(this, "director"));
079
080            // Bit source
081            DiscreteRandomSource bitSource = new DiscreteRandomSource(this,
082                    "bitSource");
083
084            // Signals
085            Const signal1 = new Const(this, "signal1");
086            // signal1.value.setToken(new DoubleMatrixToken(
087            //         new double[][] {{ 1, 1, 1, 1, 1, 1, 1, 1 }}));
088            signal1.value.setExpression("{1, 1, 1, 1, 1, 1, 1, 1}");
089
090            Const signal2 = new Const(this, "signal2");
091            // signal2.value.setToken(new DoubleMatrixToken(
092            //         new double[][] {{ 1, 1, 1, 1, -1, -1, -1, -1 }}));
093            signal2.value.setExpression("{1, 1, 1, 1, -1, -1 ,-1 ,-1}");
094
095            // Signal selector
096            Multiplexor mux = new Multiplexor(this, "mux");
097
098            // Adder
099            AddSubtract adder = new AddSubtract(this, "adder");
100
101            // Gaussian noise
102            Gaussian noise = new Gaussian(this, "noise");
103            noise.standardDeviation.setToken(new DoubleToken(2.0));
104
105            // Convert noise samples into matrix.
106            // SequenceToDoubleMatrix noisePacker =
107            //     new SequenceToDoubleMatrix(this, "noisePacker");
108            SequenceToArray noisePacker = new SequenceToArray(this,
109                    "noisePacker");
110
111            // Pack 8 samples into each matrix.
112            // noisePacker.columns.setToken(new IntToken(8));
113            noisePacker.arrayLength.setToken(new IntToken(8));
114
115            // Correlators
116            DotProduct correlator1 = new DotProduct(this, "correlator1");
117            DotProduct correlator2 = new DotProduct(this, "correlator2");
118
119            // Decision
120            Maximum decision = new Maximum(this, "decision");
121
122            // Displays
123            ExpressionWriter outputBitDisplay = new ExpressionWriter(this,
124                    "outputBitDisplay");
125
126            AddSubtract diff = new AddSubtract(this, "diff");
127
128            // Connect everything up.
129            TypedIORelation r0 = (TypedIORelation) newRelation("r0");
130            bitSource.output.link(r0);
131            mux.select.link(r0);
132            diff.plus.link(r0);
133
134            TypedIORelation r1 = (TypedIORelation) newRelation("r1");
135            signal1.output.link(r1);
136            mux.input.link(r1);
137            correlator1.input1.link(r1);
138
139            TypedIORelation r2 = (TypedIORelation) newRelation("r2");
140            signal2.output.link(r2);
141            mux.input.link(r2);
142            correlator2.input1.link(r2);
143
144            TypedIORelation r3 = (TypedIORelation) newRelation("r3");
145            adder.output.link(r3);
146            correlator1.input2.link(r3);
147            correlator2.input2.link(r3);
148
149            connect(noise.output, noisePacker.input);
150
151            connect(mux.output, adder.plus);
152            connect(noisePacker.output, adder.plus);
153
154            connect(correlator1.output, decision.input);
155            connect(correlator2.output, decision.input);
156
157            connect(decision.maximumValue, diff.minus);
158
159            connect(diff.output, outputBitDisplay.input);
160
161            // A hack to get code generation to work.
162            outputBitDisplay.input.setTypeEquals(BaseType.INT);
163
164            // Uncomment the next line dump out xml.
165            // System.out.println(exportMoML());
166
167        } catch (NameDuplicationException nde) {
168            throw new RuntimeException(nde.toString());
169        }
170    }
171}