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

📄 subassign.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 assigning a sub matrix to another matrix   */
/* (e.g.: subassign(a,b,1,1:2) will assign matrix b to matrix a.       */
/* Matrix indices start with <b>1</b> and <b>not</b> with <b>0</b>.    */
public class subassign extends ExternalFunction
{
    
    boolean leftCellB = false;
    
    public void setLeftCell()
    {
        leftCellB = true;
    }

        
	/**return a sub matrix and assign a submatrix
	@param operands[0] = original matrix 
	@param operands[1] = replacement matrix 
	@param operands[1] = vertical limits (1 or 1:3 or : ) 
	@param operands[2] = horizontal limits (optional) (1 or 1:3 or : )
	(e.g.: a= subassign(a,b,1,1) assigns the value b to the element (1,1) of matrix a, 
     a = subassign(a,b,:,2)      assigns b as the second column of a,
     a = subassign(a,b,2:3,0:2)  assigns b as a 2-by-3 submatrix of a,
	 a = subassign(a,b,2) returns the first element of the second row of a*/
	public OperandToken evaluate(Token[] operands)
	{
        DataToken retToken = null;

		// at least three operands (e.g. subassign(a,b,2) )
        // maximum is 4 operands (e.g. a=subassign(a,b,2,4) )
		if ((getNArgIn(operands)<3) ||
            (getNArgIn(operands)>4)    )
			throwMathLibException("SubAssign: number of arguments < 3 or >4");

        if (operands[0]!=null) debugLine("SubAssign1: "+operands[0].toString());
        if (operands[1]!=null) debugLine("SubAssign2: "+operands[1].toString());
        if (operands[2]!=null) debugLine("SubAssign3: "+operands[2].toString());

		// first two operands must be DataTokens (e.g. subassign(a,b,..) )
		if ((operands[0] != null)                &&
	        (!(operands[0] instanceof DataToken))   ) 
		    throwMathLibException("SubAssign: first argument must be a data token");

        if  (!(operands[1] instanceof DataToken))     
			throwMathLibException("SubAssign: second argument must be a data token");
		
        // e.g. a={3,4,5}  then a(2)=99 is wrong, must be a(2)={99}
        // because "a" is a cell array.
        if ( !leftCellB && 
            (operands[0] instanceof CellArrayToken) &&
            !(operands[1] instanceof CellArrayToken)    )
            throwMathLibException("SubAssign: conversion to cell from something not possible");
        
		// values of the original matrix
        int dy = 0;
		int	dx = 0; 
		if (operands[0]!=null)
        {
            // original matrix does not have any values yet
            // e.g. subassign(null,9,1)
		    dy          = ((DataToken)operands[0]).getSizeY(); 
            dx          = ((DataToken)operands[0]).getSizeX();
        }
		else
        {
		    // e.g. subassign(null,888,3)
            // create return token as same type as '888'
		    operands[0] = ((DataToken)operands[1]).getElementSized(1,1);
        }
        
        // size of replacement matrix  
		int dy_r = ((DataToken)operands[1]).getSizeY(); 
		int	dx_r = ((DataToken)operands[1]).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
        int        dy_max    = 0;

        // 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
        int        dx_max    = 0;

        // evaluate vertical selection (e.g. subassign(a,<....>,3) )
        if(operands[2] instanceof DoubleNumberToken)
        {
            // e.g. submatrix(a,<number>) or submatrix(a,<number>,4)
            // submatrix(a,3:5) 
        }
        else if(operands[2] instanceof Expression)
        {
            // e.g.  submatrix(a,:) or submatrix(a,2:end)
            Expression    expr = (Expression)operands[2];
            OperatorToken op   = (OperatorToken)expr.getData();

            debugLine("submatrix expr="+operands[2].toString());
            
            // 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)==3)
                    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)==3)
                    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)==3)
                    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[2]= colonOp;

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

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

        // find highest index
        for (int xi=0; xi<y_dx; xi++)
        {
            for (int yi=0; yi<y_dy ; yi++)
            {
                if (y_indexes[yi][xi]> dy_max)
                    dy_max = (int)y_indexes[yi][xi];
                if (y_indexes[yi][xi]<=0)
                    throwMathLibException("SubMatrix: index y <=0");
            }
        }
        debugLine("SubMatrix: dy_max "+dy_max);
        
        // evaluate horizontal selection (e.g. subassign(a,b,3,<...>) )
        if(operands.length==4)
        {
            debugLine("SubMatrix: "+operands[3].toString());
            
            if(operands[3] instanceof DoubleNumberToken)
            {
                // e.g. submatrix(a,1,<some array>)
                // e.g. submatrix(a,1,2) 
            }
            else if(operands[3] instanceof Expression)
            {
                // e.g.  submatrix(a,:) or submatrix(a,2:end)
                Expression    expr = (Expression)operands[3];
                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;

                if (expr.getNumberOfChildren() == 2)
                {
                    // submatrix(a,3,4:end)
                    OperandToken left  = expr.getChild(0);
                    OperandToken right = expr.getChild(1);
                        
                    if ( (!(right instanceof DelimiterToken))                   ||
                         (!((DelimiterToken)right).getWordValue().equals("end"))  )
                            throwMathLibException("SubMatrix: wrong delimiter");
                    
                    // if three arguments: e.g. submatrix(a,3,4:end) -> 4:dx
                    right = new DoubleNumberToken(dx);

                    // create new ColonOperator and return new indexes
                    colonOp = new Expression(new ColonOperatorToken(), left, right);
                }
                else if (expr.getNumberOfChildren() == 3)
                {
                    // e.g. (2:3:end)
                    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");
                    
                    // if three arguments: e.g. submatrix(a,3,4:2:end) -> 4:2:dx
                    right = new DoubleNumberToken(dx);

                    // create new ColonOperator and return new indexes

⌨️ 快捷键说明

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