⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 submatrix.java

📁 JAVA 数学程序库 提供常规的数值计算程序包
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package jmathlib.toolbox.jmathlib.matrix;

import jmathlib.core.tokens.*;
import jmathlib.core.tokens.numbertokens.DoubleNumberToken;
import jmathlib.core.functions.ExternalFunction;
import jmathlib.core.interpreter.*;

/**An external function for creating a sub matrix of a DoubleNumberToken           */
/* (e.g.: submatrix(a,1,1:2) will return the the elements 1 and 2 from row 1 */
public class submatrix extends ExternalFunction
{

    boolean leftCellB = false;
    
    public void setLeftCell()
    {
        leftCellB = true;
    }

	/**return a sub matrix 
	@param operands[0] = matrix 
	@param operands[1] = vertical limits (1 or 1:3 or : ) 
	@param operands[2] = horizontal limits (optional) (1 or 1:3 or : )
	(e.g.: submatrix(a,0,0) returns the top left element of a,      	<br>
     submatrix(a,:,2) returns the second column of a,					<br>
     submatrix(a,2:3,0:2) returns a 2-by-3 submatrix of a,				<br>
	 submatrix(a,2) returns the first element of the second row of a	<br>
     e.g.: a=[1,2,3,4,5; 												<br>
              6,7,8,9,10;												<br>
              1,2,3,4,5]                                                <br>
     then  submatrix(a,1,2)   returns 2                                 <br>
     then  submatrix(a,3,:)   returns [3,8,3]'	       					<br>
     then  submatrix(a,2:5,2) returns [7,8,9,10] 						<br>
     then  submatrix(a,:)     return [1,2,3,4,5,6,7,8,9...]' column     <br>
         (also see subassign() )
     */
	public OperandToken evaluate(Token[] operands)
	{

		// at least two operands (e.g. submatrix(a,2) )
		if ((getNArgIn(operands)<2) || (getNArgIn(operands)>3))
			throwMathLibException("SubMatrix: number of arguments <2 or >3");

		// first operand must be a DoubleNumberToken
		if (!(operands[0] instanceof DataToken))
			throwMathLibException("SubMatrix: first argument must be a data token");
		
		// values of the data array 
		int        dy        = ((DataToken)operands[0]).getSizeY(); 
		int		   dx        = ((DataToken)operands[0]).getSizeX(); 

        // first limit (y-limit)
        int        y_dy      = 0;    // y-size of first limit 
        int        y_dx      = 0;    // x-size of first limit 
        double[][] y_indexes = null; // elements

        // second limit (x-limit)
        int        x_dy      = 0;    // y-size of second limit 
        int        x_dx      = 0;    // x-size of second limit 
        double[][] x_indexes = null; // elements


		ErrorLogger.debugLine("SubMatrix: "+operands[1].toString());

		// evaluate VERTICAL selection (e.g. submatrix(a,<something>,3) )     
		if(operands[1] instanceof DoubleNumberToken)
		{
			// e.g. submatrix(a,<number>) or submatrix(a,<number>,4)
            // submatrix(a,3:5) 
		}
        else if(operands[1] instanceof LogicalToken)
        {
            // e.g. submatrix(a,[true,true,false,true])
            LogicalToken l = (LogicalToken)operands[1];
            
            // find number of elements unequal zero
            int n = 0;
            for (int i=0; i<l.getNumberOfElements(); i++)
            {
                if (l.getValue(i))
                    n++;
            }
            
            // create index array from boolean values
            // eg. a=[true,true,false,true] ->[1,2,4] (use indices with "true")
            double[][] values = new double [1][n];
            int ni =0;
            for (int i=0; i<l.getNumberOfElements(); i++)
            {
                if (l.getValue(i))
                {
                  values[0][ni] = (double)i + 1;
                  ni++;
                }
            }            
            operands[1] = new DoubleNumberToken(values,null);
            
        }
        else if(operands[1] instanceof Expression)
		{
			// e.g.  submatrix(a,:) or submatrix(a,2:end)
			Expression    expr = (Expression)operands[1];
			OperatorToken op   = (OperatorToken)expr.getData();

            // check if expression contains colon, e.g. (:) , (3:end)
            if ((op == null)                         ||
                (!(op instanceof ColonOperatorToken))  )
                throwMathLibException("SubMatrix: colon error");

            OperandToken colonOp = null;
            
			// possible colon operations. e.g. (:),(2:end),(2:3:end)
            if (expr.getNumberOfChildren() == 2)
			{
				// Get operands (e.g. <1>:<5>)
				OperandToken left  = expr.getChild(0);
				OperandToken right = expr.getChild(1);
                    
                if ( (!(right instanceof DelimiterToken))                   ||
                     (!((DelimiterToken)right).getWordValue().equals("end"))  )
                        throwMathLibException("SubMatrix: wrong delimiter");
                
                // "end" delimiter indicates total number of values or
                //   just the number of rows
                // if two   arguments: e.g. submatrix(a,3:end)     -> 3:dy*dx 
                // if three arguments: e.g. submatrix(a,3:end,4:8) -> 3:dy
                if (getNArgIn(operands)==2)
                    right = new DoubleNumberToken(dy*dx);
                else
                    right = new DoubleNumberToken(dy);

                // create new ColonOperator and return new indexes
                colonOp = new Expression(new ColonOperatorToken(), left, right);
            }
            else if (expr.getNumberOfChildren() == 3)
            {
                // e.g. (2:3:end)
                // Get operands (e.g. <1>:<5>)
                OperandToken left   = expr.getChild(0);
                OperandToken middle = expr.getChild(1);
                OperandToken right  = expr.getChild(2);
                    
                if ( (!(right instanceof DelimiterToken))                   ||
                     (!((DelimiterToken)right).getWordValue().equals("end"))  )
                        throwMathLibException("SubMatrix: wrong delimiter");
                
                // "end" delimiter indicates total number of values or
                //   just the number of rows
                // if two   arguments: e.g. submatrix(a,3:2:end)     -> 3:2:dy*dx 
                // if three arguments: e.g. submatrix(a,3:2:end,4:8) -> 3:2:dy
                if (getNArgIn(operands)==2)
                    right = new DoubleNumberToken(dy*dx);
                else
                    right = new DoubleNumberToken(dy);

                // create new ColonOperator and return new indexes
                colonOp = new Expression(new ColonOperatorToken(), left, middle, right);
            }
			else if (expr.getNumberOfChildren() == 0)
			{
                // ":" indicates all indexes of matrix/rows
                // if two   arguments: e.g. submatrix(a,:)   -> ALL elements
                // if three arguments: e.g. submatrix(a,3,:) -> all rows
                int len = 0;
                if (getNArgIn(operands)==2)
                    len = (dy*dx);
                else
                    len = dy;

                colonOp = new Expression(new ColonOperatorToken(),
                                         new DoubleNumberToken(1),
                                         new DoubleNumberToken(len)    );

            }
            else
                throwMathLibException("SubMatrix: colon wrong number of childs");

            // evaluate new colon expression
            colonOp = colonOp.evaluate(null);
            
            if ( !(colonOp instanceof DoubleNumberToken))
                throwMathLibException("SubMatrix: colon error wrong type");
              
            // e.g. a(:) must return a column vector
            if (getNArgIn(operands)==2)
                colonOp = colonOp.transpose();

            // copy new array of indices to second operand of SubMatrix
            operands[1]= colonOp;

        }
        else
           	throwMathLibException("SubMatrix: eval: unknown operand");

        // get limits size and indices
        y_dy      = ((DoubleNumberToken)operands[1]).getSizeY();
        y_dx      = ((DoubleNumberToken)operands[1]).getSizeX();
        y_indexes = ((DoubleNumberToken)operands[1]).getReValues();
        ErrorLogger.debugLine("SubMatrix: "+y_dy+" "+y_dx);

        
		/***********************************************************************/
		// create return array for e.g. submatrix(a,5) or submatrix(a,3:5)   
        // or submatrix(a,3:end) or submatrix(a,:) or submatrix(a,[1,6,2,4])
        if(getNArgIn(operands)==2)
		{
            // create return array with size of limits operator
            DataToken retToken = ((DataToken)operands[0]).getElementSized(y_dy,y_dx);
            
            // copy data to return array
            for (int xi=0; xi<y_dx; xi++)
            {
                for (int yi=0; yi<y_dy ; yi++)
                {
                    int index = (int)y_indexes[yi][xi]-1;
                    if ((index<0) || (index>dy*dx-1))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -