/* * Copyright 2006, United States Government as represented by the Administrator * for the National Aeronautics and Space Administration. No copyright is * claimed in the United States under Title 17, U.S. Code. All Other Rights * Reserved. * * Created on Mar 31, 2004 */ package gov.nasa.ial.mde.solver; import gov.nasa.ial.mde.math.PointXY; import gov.nasa.ial.mde.math.RealZero; import gov.nasa.ial.mde.util.MathUtil; /** * The class represents an interval endpoint. * * @author Dr. Robert Shelton * @version 1.0 * @since 1.0 */ public class IntervalEndpoint implements Comparable<Object> { /** The state of the interval endpoint. */ protected final static int UNDEFINED = -1, LOCAL_MIN = 0, LOCAL_MAX = 1, INFLECTION_POINT = 2, VERTICAL_ASYMPTOTE = 3, HORIZONTAL_ASYMPTOTE = 4, BOUNDARY_POINT = 5; // The strings match the array index value above. private static final String[] TYPE_STRINGS = { "local minimum", "local maximum", "inflection point", "vertical asymptote", "horizontal asymptote", "boundary point" }; /** The x value of the endpoint. */ protected double xValue; /** The left Y value of the endpoint. */ protected double leftYValue; /** The right Y value of the endpoint. */ protected double rightYValue; /** Flag indicating if the endpoint is critical. */ protected boolean isCritical = false; /** Flag indicating if the endpoint is Singular. */ protected boolean isSingular = false; private int typeCode = IntervalEndpoint.UNDEFINED; private String typeString = "undefined"; /** * Constructs an interval endpoint given the specified real-zereo value and * type. * * @param rz the real-zero value. * @param tc the type code, which is one of LOCAL_MIN, LOCAL_MAX, * INFLECTION_POINT, VERTICAL_ASYMPTOTE, HORIZONTAL_ASYMPTOTE, or * BOUNDARY_POINT. */ public IntervalEndpoint(RealZero rz, int tc) { xValue = rz.getX(); switch (this.typeCode = tc) { case IntervalEndpoint.LOCAL_MAX: case IntervalEndpoint.LOCAL_MIN: case IntervalEndpoint.INFLECTION_POINT: isCritical = true; break; case IntervalEndpoint.VERTICAL_ASYMPTOTE: isSingular = true; break; } // end switch typeString = TYPE_STRINGS[tc]; } // end IntervalEndpoint /** * Constructs an interval endpoint given the specified point. * * @param p the XY point. */ public IntervalEndpoint(PointXY p) { xValue = p.x; leftYValue = rightYValue = p.y; isCritical = false; isSingular = false; if (!Double.isInfinite(leftYValue)) { if (Double.isInfinite(xValue)) typeString = TYPE_STRINGS[typeCode = IntervalEndpoint.HORIZONTAL_ASYMPTOTE]; else typeString = TYPE_STRINGS[typeCode = IntervalEndpoint.BOUNDARY_POINT]; } // end if } // end IntervalEndpoint /** * Constructs an interval endpoint given the specified point and type. * * @param p the XY point. * @param tc the type code, which is one of LOCAL_MIN, LOCAL_MAX, * INFLECTION_POINT, VERTICAL_ASYMPTOTE, HORIZONTAL_ASYMPTOTE, or * BOUNDARY_POINT. */ public IntervalEndpoint(PointXY p, int tc) { this(p); if (0 > tc || tc >= TYPE_STRINGS.length) { typeCode = IntervalEndpoint.UNDEFINED; typeString = "undefined"; } // end if else typeString = TYPE_STRINGS[typeCode = tc]; } // end IntervalEndpoint /* (non-Javadoc) * @see java.lang.Comparable#compareTo(T) */ public int compareTo(Object o) { IntervalEndpoint e = (IntervalEndpoint)o; if (xValue < e.xValue) return -1; if (xValue > e.xValue) return 1; return 0; } // end compareTo /** * Returns the interval type as a string. * * @return the interval type as a string. */ public String getTypeString() { return typeString; } /** * Returns the interval type. * * @return the interval type. */ public int getTypeCode() { return typeCode; } /** * Returns the MDE feature node for the interval endpoint. * * @return the MDE feature node for the interval endpoint. */ public MdeFeatureNode getMFN() { MdeFeatureNode r = new MdeFeatureNode(); r.addKey("X"); // r.addValue ("X", new NumberModel(xValue).getMFN()); r.addValue("X", MathUtil.trimDouble(xValue, 3)); if (leftYValue != rightYValue) { r.addKey("discontinuity"); r.addValue("discontinuity", "true"); r.addKey("leftY"); r.addKey("rightY"); // r.addValue("leftY", new NumberModel(leftYValue).getMFN()); // r.addValue ("rightY", new NumberModel(rightYValue).getMFN()); r.addValue("leftY", MathUtil.trimDouble(leftYValue, 3)); r.addValue("rightY", MathUtil.trimDouble(rightYValue, 3)); } // end if else { r.addKey("Y"); // r.addValue ("Y", new NumberModel(leftYValue).getMFN()); r.addValue("Y", MathUtil.trimDouble(leftYValue, 3)); } // end else if (typeCode != IntervalEndpoint.UNDEFINED) { r.addKey("Type"); r.addValue("Type", getTypeString()); } // end if return r; } // end getMFN } // end class IntervalEndpoint