📄 sparsenumbertoken.java
字号:
/**Multiplies two complex numbers
@param arg1 = the first complex number as an array of double
@param arg2 = the second complex number as an array of double
@return the result as an array of double*/
public double[] multiply(double[] arg1, double[]arg2)
{
double[] temp = new double[2];
temp[REAL] = (arg1[REAL] * arg2[REAL]) - (arg1[IMAGINARY] * arg2[IMAGINARY]);
temp[IMAGINARY] = (arg1[REAL] * arg2[IMAGINARY]) + (arg1[IMAGINARY] * arg2[REAL]);
return temp;
}
/**divide this object by arg for a number token
@param arg = the value to divide it by
@return the result as an OperandToken*/
public OperandToken divide(OperandToken arg)
{
if(!(arg instanceof DoubleNumberToken))
Errors.throwMathLibException("DoubleNumberToken: divide: no number");
DoubleNumberToken nArg = (DoubleNumberToken)arg;
int argSizeX = nArg.getSizeX();
int argSizeY = nArg.getSizeY();
// Check if arg is a scalar
if((argSizeX == 1) && (argSizeY == 1))
{
DoubleNumberToken result = new DoubleNumberToken(values); //this);
// Divide (n*m) = (n*m) / scalar
double[] argValue = nArg.getValueComplex(0, 0);
ErrorLogger.debugLine("DoubleNumberToken: divide (n*m) / scalar");
for (int yy=0; yy<sizeY; yy++)
{
for (int xx=0; xx<sizeX; xx++)
{
result.setValueComplex(yy, xx, divide(values[yy][xx], argValue));
}
}
return result;
}
else if((sizeX == 1) && (sizeY == 1))
{
// the DoubleNumberToken of this class is a scalar
// Divide (n*m) = scalar / (n*m)
ErrorLogger.debugLine("DoubleNumberToken: divide scalar / (n*m) ");
DoubleNumberToken result = new DoubleNumberToken(1);
double[] value = values[0][0];
for (int yy=0; yy<argSizeY; yy++)
{
for (int xx=0; xx<argSizeX; xx++)
{
result.setValueComplex(yy, xx, divide(value, nArg.getValueComplex(yy, xx)));
}
}
return result;
}
else
{
ErrorLogger.debugLine("DoubleNumberToken: divide: dimensions don't match");
return null;
}
} // end divide
/** divide two complex numbers and return a complex number again,
pay special attention to infinity and not a number
@param arg1 = the first complex number as an array of double
@param arg2 = the second complex number as an array of double
@return the result as an array of double*/
public double[] divide(double[] arg1, double[] arg2)
{
/* {REAL,IMAGINARY} = divide( {REAL,IMAGINARY}, {REAL,IMAGINARY}) */
double x = arg2[REAL];
double y = arg2[IMAGINARY];
double zRe, zIm;
double scalar;
double[] temp = new double[2];
if ((x==0.0) && (y==0.0))
{
// something like 1/0 50/0 or 0/0
// real part
if (Double.isNaN(arg1[REAL]))
zRe = Double.NaN;
else if (arg1[REAL]>0)
zRe = Double.POSITIVE_INFINITY;
else if (arg1[REAL]<0)
zRe = Double.NEGATIVE_INFINITY;
else
zRe = Double.NaN;
// something like (1+i)/0 50i/0
// imaginary part
if (Double.isNaN(arg1[IMAGINARY]))
zIm = Double.NaN;
else if (arg1[IMAGINARY]>0)
zIm = Double.POSITIVE_INFINITY;
else if (arg1[IMAGINARY]<0)
zIm = Double.NEGATIVE_INFINITY;
else
zIm = 0.0;
}
else if(Math.abs(x) >= Math.abs(y))
{
scalar = 1.0 / ( x + y*(y/x) );
zRe = scalar * (arg1[REAL] + arg1[IMAGINARY]*(y/x));
zIm = scalar * (arg1[IMAGINARY] - arg1[REAL]*(y/x));
}
else
{
scalar = 1.0 / ( x*(x/y) + y );
zRe = scalar * (arg1[REAL]*(x/y) + arg1[IMAGINARY]);
zIm = scalar * (arg1[IMAGINARY]*(x/y) - arg1[REAL]);
}
temp[REAL] = zRe;
temp[IMAGINARY] = zIm;
return temp;
}
//////////////////////////////////////////SCALAR OPERATORS//////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////
/**scalar multiply arg by this object for a number token
@arg = the value to multiply it by
@return the result as an OperandToken*/
public OperandToken scalarMultiply(OperandToken arg)
{
if(!(arg instanceof DoubleNumberToken))
Errors.throwMathLibException("DoubleNumberToken: scalar multiply: no number");
DoubleNumberToken nArg = ((DoubleNumberToken)arg);
double[][] argValues = nArg.getValuesIm();
double[][] argValuesImg = nArg.getValuesIm();
int argSizeX = nArg.getSizeX();
int argSizeY = nArg.getSizeY();
if ((sizeX == argSizeX) && (sizeY == argSizeY))
{
// scalar multiplication (n*m) = (n*m) .* (n*m)
ErrorLogger.debugLine("DoubleNumberToken: multiply (n*m) .* (n*m)");
double[][][] results = new double[sizeY][sizeX][2];
for (int y=0; y<sizeY; y++)
{
for (int x=0; x<sizeX; x++)
{
double[] argVal = nArg.getValueComplex(y, x);
results[y][x] = multiply(values[y][x], argVal);
}
}
return new DoubleNumberToken(results);
}
else if ((argSizeX==1) && (argSizeY==1))
{
// scalar multiplication (n*m) .* (1*1)
ErrorLogger.debugLine("DoubleNumberToken: multiply (n*m) .* (1*1)");
double[][][] results = new double[sizeY][sizeX][2];
for (int y=0; y<sizeY; y++)
{
for (int x=0; x<sizeX; x++)
{
double[] argVal = nArg.getValueComplex(0, 0);
results[y][x] = multiply(values[y][x], argVal);
}
}
return new DoubleNumberToken(results);
}
else if ((sizeX == 1) && (sizeY == 1))
{
// scalar multiplication (1*1) .* (n*m)
ErrorLogger.debugLine("DoubleNumberToken: multiply (1*1) .* (n*m)");
double[][][] results = new double[argSizeY][argSizeX][2];
for (int y=0; y<argSizeY; y++)
{
for (int x=0; x<argSizeX; x++)
{
double[] val = getValueComplex(0, 0);
results[y][x] = multiply(val, nArg.getValueComplex(y,x));
}
}
return new DoubleNumberToken(results);
}
else
{
//dimensions do not match
Errors.throwMathLibException("DoubleNumberToken: scalar multiply: dimensions don't match");
return null;
}
} // end scalarMultiply
/**scalar divide arg by this object for a number token
@arg = the value to divide it by
@return the result as an OperandToken*/
public OperandToken scalarDivide(OperandToken arg)
{
if(!(arg instanceof DoubleNumberToken))
Errors.throwMathLibException("DoubleNumberToken: scalar divide: no number");
DoubleNumberToken nArg = ((DoubleNumberToken)arg);
double[][] argValues = nArg.getValuesRe();
double[][] argValuesImg = nArg.getValuesIm();
int argSizeX = nArg.getSizeX();
int argSizeY = nArg.getSizeY();
if ((sizeX == argSizeX) && (sizeY == argSizeY))
{
// divide multiplication (n*m) = (n*m) .* (n*m)
ErrorLogger.debugLine("DoubleNumberToken: scalar divide (n*m) .* (n*m)");
double[][][] results = new double[sizeY][sizeX][2];
for (int y=0; y<sizeY; y++)
{
for (int x=0; x<sizeX; x++)
{
double[] argVal = nArg.getValueComplex(y, x);
results[y][x] = divide(values[y][x], argVal);
}
}
return new DoubleNumberToken(results);
}
else if ((argSizeX==1) && (argSizeY==1))
{
// divide multiplication (n*m) ./ (1,1)
ErrorLogger.debugLine("DoubleNumberToken: scalar divide (n*m) ./ (1*1)");
double[][][] results = new double[sizeY][sizeX][2];
for (int y=0; y<sizeY; y++)
{
for (int x=0; x<sizeX; x++)
{
double[] argVal = nArg.getValueComplex(0, 0);
results[y][x] = divide(values[y][x], argVal);
}
}
return new DoubleNumberToken(results);
}
else if ((sizeX==1) && (sizeY==1))
{
// divide multiplication (n*m) ./ (1,1)
ErrorLogger.debugLine("DoubleNumberToken: scalar divide (1*1) ./ (n*m)");
double[][][] results = new double[argSizeY][argSizeX][2];
for (int y=0; y<argSizeY; y++)
{
for (int x=0; x<argSizeX; x++)
{
double[] val = getValueComplex(0, 0);
results[y][x] = divide(val, nArg.getValueComplex(y,x) );
}
}
return new DoubleNumberToken(results);
}
else
{
//dimensions do not match
Errors.throwMathLibException("DoubleNumberToken: scalar multiply: dimensions don't match");
return null;
}
} // end scalarDivide
/**left divide
@arg =
@return the result as an OperandToken*/
public OperandToken leftDivide(OperandToken arg)
{
if(!(arg instanceof DoubleNumberToken))
Errors.throwMathLibException("DoubleNumberToken: left divide: no number");
DoubleNumberToken nArg = ((DoubleNumberToken)arg);
DoubleNumberToken num = new DoubleNumberToken(nArg.getReValues());
return num.divide(new DoubleNumberToken(values));
} // end leftDivide
/**scalar left divide
@arg =
@return the result as an OperandToken*/
public OperandToken scalarLeftDivide(OperandToken arg)
{
if(!(arg instanceof DoubleNumberToken))
Errors.throwMathLibException("DoubleNumberToken: scalar left divide: no number");
DoubleNumberToken nArg = ((DoubleNumberToken)arg);
DoubleNumberToken num = new DoubleNumberToken(nArg.getReValues());
return num.scalarDivide(new DoubleNumberToken(values));
} // end scalarLeftDivide
/**calculate the transpose of a matrix
@return the result as an OperandToken*/
public OperandToken transpose()
{
// transposed array
double[][] real = new double[sizeX][sizeY];
double[][] imag = new double[sizeX][sizeY];
// swap rows and columns
for (int y=0; y<sizeY; y++)
{
for (int x=0; x<sizeX; x++)
{
// copy (y,x) -> (x,y), also change sign of imaginary part
real[x][y] = values[y][x][REAL];
imag[x][y] = values[y][x][IMAGINARY] * (-1);
}
}
return new DoubleNumberToken(real, imag);
}
/**calculate the conjugate transpose of a matrix
@return the result as an OperandToken*/
public OperandToken ctranspose()
{
// transposed array
double[][] real = new double[sizeX][sizeY];
double[][] imag = new double[sizeX][sizeY];
// swap rows and columns
for (int y=0; y<sizeY; y++)
{
for (int x=0; x<sizeX; x++)
{
// copy (y,x) -> (x,y), for conjugate transpose do not
// change sign of imaginary part
real[x][y] = values[y][x][REAL];
imag[x][y] = values[y][x][IMAGINARY] ;
}
}
return new DoubleNumberToken(real, imag);
}
///////////////////////////////////////Trigonometric functions/////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
/**trigonometric functions - calculate the sine of this token
@return the result as an OperandToken*/
public OperandToken sin()
{
double[][][] results = new double[sizeY][sizeX][2];
for(int y = 0; y < sizeY; y++)
{
for(int x = 0; x < sizeX; x++)
{
results[y][x] = sin(values[y][x]);
}
}
return new DoubleNumberToken(results);
}
/**Calculates the sine of a complex number
@param arg = the angle as an array of double
@return the result as an array of double*/
public double[] sin(double[] arg)
{
double result[] = new double[2];
double scalar;
double iz_re, iz_im;
double _re1, _im1;
double _re2, _im2;
// iz: i.Times(z) ...
iz_re = -arg[IMAGINARY];
iz_im = arg[REAL];
// _1: iz.exp() ...
scalar = Math.exp(iz_re);
_re1 = scalar * Math.cos(iz_im);
_im1 = scalar * Math.sin(iz_im);
// _2: iz.neg().exp() ...
scalar = Math.exp(-iz_re);
_re2 = scalar * Math.cos(-iz_im);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -