001/* An actor that outputs a random sequence with a Binomial distribution. 002 003 Copyright (c) 2004-2016 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.actor.lib.colt; 029 030import cern.jet.random.Binomial; 031import ptolemy.actor.parameters.PortParameter; 032import ptolemy.data.BooleanToken; 033import ptolemy.data.DoubleToken; 034import ptolemy.data.IntToken; 035import ptolemy.data.expr.SingletonParameter; 036import ptolemy.data.type.BaseType; 037import ptolemy.kernel.CompositeEntity; 038import ptolemy.kernel.util.IllegalActionException; 039import ptolemy.kernel.util.NameDuplicationException; 040 041/////////////////////////////////////////////////////////////////// 042//// Binomial 043 044/** 045 Produce a random sequence with a Binomial distribution. On each 046 iteration, a new random number is produced. The output port is of 047 type DoubleToken. The values that are generated are independent 048 and identically distributed with the mean and the standard 049 deviation given by parameters. In addition, the seed can be 050 specified as a parameter to control the sequence that is generated. 051 052 <p> This actor instantiates a 053 <a href="http://hoschek.home.cern.ch/hoschek/colt/V1.0.3/doc/cern/jet/random/Binomial.html">cern.jet.random.Binomial</a> object with 054 n, the number of trials (also known as the sample size) set to 1 055 and p, the probability of success, set to 0.5. 056 057 A definition of Binomial by Wolfgang Hoschek can be found at 058 <a href="http://hoschek.home.cern.ch/hoschek/colt/V1.0.3/doc/cern/jet/stat/Probability.html#binomial(int,%20int,%20double)"><code>http://hoschek.home.cern.ch/hoschek/colt/V1.0.3/doc/cern/jet/stat/Probability.html#binomial(int,%20int,%20double)</code></a>: 059 <blockquote> 060 <h3> 061 binomial</h3> 062 <pre>public static double <b>binomial</b>(int k, 063 int n, 064 double p)</pre> 065 066 <p>Returns the sum of the terms <tt>0</tt> through <tt>k</tt> of the Binomial 067 probability density. 068 <pre> k 069 -- ( n ) j n-j 070 > ( ) p (1-p) 071 -- ( j ) 072 j=0 073 </pre> 074 The terms are not summed directly; instead the incomplete 075 beta integral is employed, according to the formula 076 <p> 077 <tt>y = binomial( k, n, p ) = Gamma.incompleteBeta( n-k, k+1, 1-p )</tt>. 078 </p><p> 079 080 All arguments must be positive,</p> 081 <p><b>Parameters:</b> 082 <br><code>k</code> - end term. 083 <br><code>n</code> - the number of trials. 084 <br><code>p</code> - the probability of success (must be in <tt>(0.0,1.0)</tt>). 085 </blockquote> 086 The above description of binomial() is 087 <a href="doc-files/colt-copyright.htm">copyrighted</a>. 088 089 @author David Bauer and Kostas Oikonomou 090 @version $Id$ 091 @since Ptolemy II 4.1 092 @Pt.ProposedRating Red (cxh) 093 @Pt.AcceptedRating Red (cxh) 094 */ 095public class ColtBinomial extends ColtRandomSource { 096 /** Construct an actor with the given container and name. 097 * @param container The container. 098 * @param name The name of this actor. 099 * @exception IllegalActionException If the actor cannot be contained 100 * by the proposed container. 101 * @exception NameDuplicationException If the container already has an 102 * actor with this name. 103 */ 104 public ColtBinomial(CompositeEntity container, String name) 105 throws NameDuplicationException, IllegalActionException { 106 super(container, name); 107 108 output.setTypeEquals(BaseType.INT); 109 110 n = new PortParameter(this, "n", new IntToken(1)); 111 n.setTypeEquals(BaseType.INT); 112 new SingletonParameter(n.getPort(), "_showName") 113 .setToken(BooleanToken.TRUE); 114 115 p = new PortParameter(this, "p", new DoubleToken(0.5)); 116 p.setTypeEquals(BaseType.DOUBLE); 117 new SingletonParameter(p.getPort(), "_showName") 118 .setToken(BooleanToken.TRUE); 119 120 p.moveToFirst(); 121 n.moveToFirst(); 122 } 123 124 /////////////////////////////////////////////////////////////////// 125 //// ports and parameters //// 126 127 /** n. 128 * This has type int with default 1. 129 */ 130 public PortParameter n; 131 132 /** p. 133 * This has type double with default 0.5. 134 */ 135 public PortParameter p; 136 137 /////////////////////////////////////////////////////////////////// 138 //// public methods //// 139 140 /** Send a random number with a Binomial distribution to the output. 141 * This number is only changed in the prefire() method, so it will 142 * remain constant throughout an iteration. 143 * @exception IllegalActionException If there is no director. 144 */ 145 @Override 146 public void fire() throws IllegalActionException { 147 n.update(); 148 p.update(); 149 super.fire(); 150 output.send(0, new IntToken(_current)); 151 } 152 153 /////////////////////////////////////////////////////////////////// 154 //// protected methods //// 155 156 /** Method that is called after _randomNumberGenerator is changed. 157 */ 158 @Override 159 protected void _createdNewRandomNumberGenerator() { 160 _generator = new Binomial(1, 0.5, _randomNumberGenerator); 161 } 162 163 /** Generate a new random number. 164 * @exception IllegalActionException If parameter values are incorrect. 165 */ 166 @Override 167 protected void _generateRandomNumber() throws IllegalActionException { 168 169 // The following logic protects the binomial generation call 170 // because the Colt library will throw an exception (even 171 // though they are valid limit cases). The limits can occur 172 // during the course of a simulation, and this actor should 173 // produce valid results if they do occur. 174 175 int nValue = ((IntToken) n.getToken()).intValue(); 176 if (nValue == 0) { 177 _current = 0; 178 } else { 179 double pValue = ((DoubleToken) p.getToken()).doubleValue(); 180 if (pValue == 0.0) { 181 _current = 0; 182 } else if (pValue == 1.0) { 183 _current = nValue; 184 } else { 185 _current = _generator.nextInt(nValue, pValue); 186 } 187 } 188 } 189 190 /////////////////////////////////////////////////////////////////// 191 //// private variables //// 192 193 /** The random number for the current iteration. */ 194 private int _current; 195 196 /** The random number generator. */ 197 private Binomial _generator; 198}