001/* An actor that outputs the average of the input array. 002 003 Copyright (c) 2003-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 */ 027package ptolemy.actor.lib; 028 029import ptolemy.data.ArrayToken; 030import ptolemy.data.IntToken; 031import ptolemy.data.Token; 032import ptolemy.data.type.ArrayType; 033import ptolemy.kernel.CompositeEntity; 034import ptolemy.kernel.util.IllegalActionException; 035import ptolemy.kernel.util.InternalErrorException; 036import ptolemy.kernel.util.NameDuplicationException; 037import ptolemy.kernel.util.Workspace; 038 039/////////////////////////////////////////////////////////////////// 040//// ArrayAverage 041 042/** 043 Compute the average of the elements in an array. This actor reads an 044 array from the <i>input</i> port and sends the average of its elements 045 to the <i>output</i> port. The output data type is at least the 046 type of the elements of the input array. The elements of the input 047 array have to support addition and division by an integer, or an 048 exception will be thrown in the fire() method. 049 050 @author Mark Oliver, Edward A. Lee 051 @version $ID: ArrayAverage.java,v0.1 2003/07/01 052 @since Ptolemy II 4.0 053 @Pt.ProposedRating Red (cxh) 054 @Pt.AcceptedRating Red (cxh) 055 */ 056public class ArrayAverage extends Transformer { 057 /** Construct an actor with the given container and name. 058 * @param container The container. 059 * @param name The name of this actor. 060 * @exception IllegalActionException If the actor cannot be contained 061 * by the proposed container. 062 * @exception NameDuplicationException If the container already has an 063 * actor with this name. 064 */ 065 public ArrayAverage(CompositeEntity container, String name) 066 throws NameDuplicationException, IllegalActionException { 067 super(container, name); 068 069 // set type constraints. 070 output.setTypeAtLeast(ArrayType.elementType(input)); 071 } 072 073 /////////////////////////////////////////////////////////////////// 074 //// public methods //// 075 076 /** Override the base class to set type constraints. 077 * @param workspace The workspace for the new object. 078 * @return A new instance of ArrayAverage. 079 * @exception CloneNotSupportedException If a derived class contains 080 * an attribute that cannot be cloned. 081 */ 082 @Override 083 public Object clone(Workspace workspace) throws CloneNotSupportedException { 084 ArrayAverage newObject = (ArrayAverage) super.clone(workspace); 085 try { 086 newObject.output 087 .setTypeAtLeast(ArrayType.elementType(newObject.input)); 088 } catch (IllegalActionException e) { 089 // Should have been caught before. 090 throw new InternalErrorException(e); 091 } 092 return newObject; 093 } 094 095 /** Consume at most one array from the input port and produce 096 * the average of its elements on the <i>output</i> port. 097 * If there is no token on the input, or if the input array 098 * is empty, then no output is produced. 099 * @exception IllegalActionException If there is no director. 100 */ 101 @Override 102 public void fire() throws IllegalActionException { 103 super.fire(); 104 if (input.hasToken(0)) { 105 ArrayToken token = (ArrayToken) input.get(0); 106 107 if (token.length() == 0) { 108 return; 109 } 110 111 Token sum = token.getElement(0); 112 113 for (int i = 1; i < token.length(); i++) { 114 sum = sum.add(token.getElement(i)); 115 } 116 117 output.send(0, sum.divide(new IntToken(token.length()))); 118 } 119 } 120}