001/* Extract a submatrix from an input matrix.
002
003 Copyright (c) 2007-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.actor.lib;
029
030import ptolemy.actor.parameters.PortParameter;
031import ptolemy.data.IntToken;
032import ptolemy.data.MatrixToken;
033import ptolemy.data.type.BaseType;
034import ptolemy.kernel.CompositeEntity;
035import ptolemy.kernel.util.IllegalActionException;
036import ptolemy.kernel.util.NameDuplicationException;
037
038///////////////////////////////////////////////////////////////////
039//// SubMatrix
040
041/**
042 This actor extract a submatrix from an input matrix.
043 For example, if the input matrix is
044 <pre>
045   1  2  3
046   4  5  6
047   7  8  9
048 </pre>
049 then the parameters <i>row</i> = 1,
050 <i>column</i> = 0,
051 <i>rowSpan</i> = 2, and
052 <i>columnSpan</i> = 1,
053 yield the following submatrix
054 <pre>
055   4
056   7
057 </pre>
058 If the submatrix specified is not entirely
059 contained by the input matrix, or if the resulting submatrix
060 is empty, then this actor will throw an exception.
061
062 @author Edward Lee
063 @version $Id$
064 @since Ptolemy II 6.1
065 @Pt.ProposedRating Yellow (eal)
066 @Pt.AcceptedRating Red (neuendor)
067 */
068public class SubMatrix extends Transformer {
069    /** Construct an actor with the given container and name.
070     *  @param container The container.
071     *  @param name The name of this actor.
072     *  @exception IllegalActionException If the actor cannot be contained
073     *   by the proposed container.
074     *  @exception NameDuplicationException If the container already has an
075     *   actor with this name.
076     */
077    public SubMatrix(CompositeEntity container, String name)
078            throws NameDuplicationException, IllegalActionException {
079        super(container, name);
080
081        row = new PortParameter(this, "row");
082        row.setTypeEquals(BaseType.INT);
083        row.setExpression("0");
084
085        column = new PortParameter(this, "column");
086        column.setTypeEquals(BaseType.INT);
087        column.setExpression("0");
088
089        rowSpan = new PortParameter(this, "rowSpan");
090        rowSpan.setTypeEquals(BaseType.INT);
091        rowSpan.setExpression("1");
092
093        columnSpan = new PortParameter(this, "columnSpan");
094        columnSpan.setTypeEquals(BaseType.INT);
095        columnSpan.setExpression("1");
096    }
097
098    ///////////////////////////////////////////////////////////////////
099    ////                         parameters                        ////
100
101    /** The starting column number. This is an integer that
102     *  defaults to 0.
103     */
104    public PortParameter column;
105
106    /** The span of columns. This is an integer that defaults
107     *  to 1.
108     */
109    public PortParameter columnSpan;
110
111    /** The starting row number. This is an integer that
112     *  defaults to 0.
113     */
114    public PortParameter row;
115
116    /** The span of rows. This is an integer that defaults
117     *  to 1.
118     */
119    public PortParameter rowSpan;
120
121    ///////////////////////////////////////////////////////////////////
122    ////                         public methods                    ////
123
124    /** Consume the input matrix and produce the output matrix.
125     *  @exception IllegalActionException If the submatrix is
126     *   empty (e.g., row and column are out of range).
127     */
128    @Override
129    public void fire() throws IllegalActionException {
130        super.fire();
131        if (!input.hasToken(0)) {
132            return;
133        }
134        row.update();
135        column.update();
136        rowSpan.update();
137        columnSpan.update();
138        int columnValue = ((IntToken) column.getToken()).intValue();
139        int rowValue = ((IntToken) row.getToken()).intValue();
140        int columnSpanValue = ((IntToken) columnSpan.getToken()).intValue();
141        int rowSpanValue = ((IntToken) rowSpan.getToken()).intValue();
142
143        // FIXME: We are not enforcing that the input is a matrix.
144        // How to do this?
145        MatrixToken inputValue = (MatrixToken) input.get(0);
146        output.send(0, inputValue.crop(rowValue, columnValue, rowSpanValue,
147                columnSpanValue));
148    }
149}