package math.functions; import java.awt.Window; import java.awt.event.ActionEvent; import org.trianacode.taskgraph.Unit; import triana.types.Const; import triana.types.EmptyingType; import triana.types.GraphType; import triana.types.util.FlatArray; /** * An ArcSinh unit to compute the inverse hyperbolic sine of the elements of an input data object. The input data can be * either GraphType or Const. The function is applied to each element of each arithmetic dependent-data array of an * input GraphType, regardless of dimensionality. * <p/> * The input data arrays can be real or complex. If the data are real, then the returned data set will be real. If the * data are complex, then the output data will be complex. * <p/> * * @author Bernard Schutz * @version 2.1 13 January 2001 */ public class ArcSinh extends Unit { double Pi2 = Math.PI / 2.0; /** * This returns a <b>brief!</b> description of what the unit does. The text here is shown in a pop up window when * the user puts the mouse over the unit icon for more than a second. */ public String getPopUpDescription() { return "Computes the inverse hyperbolic sine of the elements of the input data set"; } /** * ********************************************* ** USER CODE of ArcSinh goes here *** * ********************************************* */ public void process() { Object input, output; output = null; input = getInputAtNode(0); if (input instanceof EmptyingType) { return; } output = input; Class outputClass = output.getClass(); //setOutputType(outputClass); if (input instanceof GraphType) { FlatArray tempR, tempI; int dv, j; double p, q, ppq, tmp1, tmp2; double[] inputdataR, inputdataI; for (dv = 0; dv < ((GraphType) input).getDependentVariables(); dv++) { if (((GraphType) input).isArithmeticArray(dv)) { tempR = new FlatArray(((GraphType) input).getDataArrayReal(dv)); inputdataR = (double[]) tempR.getFlatArray(); if (((GraphType) input).isDependentComplex(dv)) { tempI = new FlatArray(((GraphType) input).getDataArrayImag(dv)); inputdataI = (double[]) tempI.getFlatArray(); for (j = 0; j < inputdataI.length; j++) { if (inputdataR[j] != 0.0) { tmp1 = 1.0 + inputdataI[j]; tmp2 = inputdataR[j] * inputdataR[j]; p = Math.sqrt(tmp1 * tmp1 + tmp2); tmp1 -= 2.0; q = Math.sqrt(tmp1 * tmp1 + tmp2); ppq = (p + q) * 0.5; inputdataI[j] = Math.asin(inputdataI[j] / ppq); tmp1 = Math.log(ppq + Math.sqrt(ppq * ppq - 1.0)); inputdataR[j] = (inputdataR[j] < 0.0) ? -tmp1 : tmp1; } else { if (inputdataI[j] >= 1.0) { inputdataR[j] = Math .log(inputdataI[j] + Math.sqrt(inputdataI[j] * inputdataI[j] - 1.0)); inputdataI[j] = Pi2; } else { if (inputdataI[j] > -1.0) { inputdataR[j] = 0.0; inputdataI[j] = Math.asin(inputdataI[j]); } else { inputdataR[j] = Math .log(-inputdataI[j] + Math.sqrt(inputdataI[j] * inputdataI[j] - 1.0)); inputdataI[j] = -Pi2; } } } } ((GraphType) output).setDataArrayReal(tempR.restoreArray(false), dv); ((GraphType) output).setDataArrayImag(tempI.restoreArray(false), dv); } else { for (j = 0; j < inputdataR.length; j++) { inputdataR[j] = Math.log(inputdataR[j] + Math.sqrt(inputdataR[j] * inputdataR[j] + 1.0)); } ((GraphType) output).setDataArrayReal(tempR.restoreArray(false), dv); } } } } else if (input instanceof Const) { double r, i, p, q, ppq, tmp1, tmp2; r = ((Const) input).getReal(); if (((Const) input).isComplex()) { i = ((Const) input).getImag(); if (r != 0.0) { tmp1 = 1.0 + i; tmp2 = r * r; p = Math.sqrt(tmp1 * tmp1 + tmp2); tmp1 -= 2.0; q = Math.sqrt(tmp1 * tmp1 + tmp2); ppq = (p + q) * 0.5; i = Math.asin(i / ppq); tmp1 = Math.log(ppq + Math.sqrt(ppq * ppq - 1.0)); r = (r < 0.0) ? -tmp1 : tmp1; } else { if (i >= 1.0) { r = Math.log(i + Math.sqrt(i * i - 1.0)); i = Pi2; } else { if (i > -1.0) { r = 0.0; i = Math.asin(i); } else { r = Math.log(-i + Math.sqrt(i * i - 1.0)); i = -Pi2; } } } ((Const) output).setImag(i); } else { r = Math.log(r + Math.sqrt(r * r + 1.0)); } ((Const) output).setReal(r); } output(output); } /** * Initialses information specific to ArcSinh. */ public void init() { super.init(); setDefaultInputNodes(1); setMinimumInputNodes(1); setMaximumInputNodes(Integer.MAX_VALUE); setDefaultOutputNodes(1); setMinimumOutputNodes(1); setMaximumOutputNodes(Integer.MAX_VALUE); // setResizableInputs(false); // setResizableOutputs(true); // // This is to ensure that we receive arrays containing double-precision numbers // setRequireDoubleInputs(true); // setCanProcessDoubleArrays(true); } /** * Resets ArcSinh */ public void reset() { super.reset(); } /** * Saves ArcSinh's parameters to the parameter file. */ public void saveParameters() { } /** * Loads ArcSinh's parameters of from the parameter file. */ public void setParameter(String name, String value) { } /** * @return a string containing the names of the types allowed to be input to ArcSinh, each separated by a white * space. */ public String[] getInputTypes() { return new String[]{"triana.types.GraphType", "triana.types.Const"}; } public String[] getOutputTypes() { return new String[]{"triana.types.GraphType", "triana.types.Const"}; } /** * * @returns the location of the help file for this unit. */ public String getHelpFile() { return "ArcSinh.html"; } /** * @return ArcSinh's parameter window sp that Triana can move and display it. */ public Window getParameterWindow() { return null; } /** * Captures the events thrown out by ArcSinh. */ // public void actionPerformed(ActionEvent e) { // super.actionPerformed(e); // we need this // // } }