1111 * Default operations with NumericProperties
1212 *
1313 */
14-
1514public class NumericProperties {
1615
17- /**
18- * The list of default properties read that is created by reading the default
19- * {@code .xml} file.
20- */
21-
22- private final static List <NumericProperty > DEFAULT = XMLConverter .readDefaultXML ();
23-
24- private NumericProperties () {
25- //empty constructor
26- }
27-
28- /**
29- * Checks whether the {@code val} that is going to be passed to the
30- * {@code property} (a) has the same type as the {@code property.getValue()}
31- * object; (b) is confined within the definition domain:
32- * {@code minimum <= value <= maximum}.
33- *
34- * @param property the {@code property} containing the definition domain
35- * @param val a numeric value, the conformity of which to the definition
36- * domain needs to be checked
37- * @return {@code true} if {@code minimum <= val <= maximum} and if both
38- * {@code val} and {@code value} are instances of the same
39- * {@code class}; {@code false} otherwise
40- */
41-
42- public static boolean isValueSensible (NumericProperty property , Number val ) {
43- if (!property .getValue ().getClass ().equals (val .getClass ()))
44- return false ;
45-
46- double v = val .doubleValue ();
47-
48- final double EPS = 1E-12 ;
49-
50- if (v > property .getMaximum ().doubleValue () + EPS )
51- return false ;
52-
53- return v >= property .getMinimum ().doubleValue () - EPS ;
54-
55- }
56-
57- public static String printRangeAndNumber (NumericProperty p , Number value ) {
58- StringBuilder msg = new StringBuilder ();
59- msg .append ("Acceptable region for " );
60- msg .append ("parameter : " );
61- msg .append (p .getValue ().getClass ().getSimpleName ());
62- msg .append (" [ " + p .getMinimum ());
63- msg .append (" : " + p .getMaximum () + " ]. " );
64- msg .append ("Value received: " + value );
65- return msg .toString ();
66- }
67-
68- public static NumberFormat numberFormat (NumericProperty p , boolean convertDimension ) {
69- var value = p .getValue ();
70-
71- if (value instanceof Integer )
72- return NumberFormat .getIntegerInstance ();
73-
74- double adjustedValue = convertDimension ? (double ) value * p .getDimensionFactor ().doubleValue ()
75- : (double ) value ;
76- double absAdjustedValue = Math .abs (adjustedValue );
77-
78- final double UPPER_LIMIT = 1e4 ; // the upper limit, used for formatting
79- final double LOWER_LIMIT = 1e-2 ; // the lower limit, used for formatting
80- final double ZERO = 1e-30 ;
81-
82- if ((absAdjustedValue > UPPER_LIMIT ) || (absAdjustedValue < LOWER_LIMIT && absAdjustedValue > ZERO ))
83- return new DecimalFormat (Messages .getString ("NumericProperty.BigNumberFormat" ));
84- else
85- return new DecimalFormat (Messages .getString ("NumericProperty.NumberFormat" ));
86- }
87-
88- public static List <NumericProperty > defaultList () {
89- return DEFAULT ;
90- }
91-
92- /**
93- * Searches for the default {@code NumericProperty} corresponding to
94- * {@code keyword} in the list of pre-defined properties loaded from the
95- * respective {@code .xml} file.
96- *
97- * @param keyword one of the constant {@code NumericPropertyKeyword}s
98- * @return a {@code NumericProperty} in the default list of properties
99- * @see pulse.properties.NumericPropertyKeyword
100- */
101-
102- public static NumericProperty def (NumericPropertyKeyword keyword ) {
103- return new NumericProperty (DEFAULT .stream ().filter (p -> p .getType () == keyword ).findFirst ().get ());
104- }
105-
106- /**
107- * Compares the numeric values of this {@code NumericProperty} and {@code arg0}
108- *
109- * @param a a {@code NumericProperty}
110- * @param b another {@code NumericProperty}
111- * @return {@code true} if the values are equals
112- */
113-
114- public static int compare (NumericProperty a , NumericProperty b ) {
115- Double d1 = ((Number ) a .getValue ()).doubleValue ();
116- Double d2 = ((Number ) b .getValue ()).doubleValue ();
117-
118- final double eps = 1E-8 * (d1 + d2 ) / 2.0 ;
119-
120- return Math .abs (d1 - d2 ) < eps ? 0 : d1 .compareTo (d2 );
121- }
122-
123- /**
124- * Searches for the default {@code NumericProperty} corresponding to
125- * {@code keyword} in the list of pre-defined properties loaded from the
126- * respective {@code .xml} file, and if found creates a new
127- * {@NumericProperty} which will replicate all field of the latter, but will set
128- * its value to {@code value}.
129- *
130- * @param keyword one of the constant {@code NumericPropertyKeyword}s
131- * @param value the new value for the created {@code NumericProperty}
132- * @return a new {@code NumericProperty} that is built according to the default
133- * pattern specified by the {@code keyword}, but with a different
134- * {@code value}
135- * @see pulse.properties.NumericPropertyKeyword
136- */
137-
138- public static NumericProperty derive (NumericPropertyKeyword keyword , Number value ) {
139- return new NumericProperty (value , DEFAULT .stream ().filter (p -> p .getType () == keyword ).findFirst ().get ());
140- }
141-
142- /**
143- * Used to print out a nice {@code value} for GUI applications and for
144- * exporting.
145- * <p>
146- * Will use a {@code DecimalFormat} to reduce the number of digits, if
147- * neccessary. Automatically detects whether it is dealing with {@code int} or
148- * {@code double} values, and adjust formatting accordingly. If
149- * {@code error != null}, will use the latter as the error value, which is
150- * separated from the main value by a plus-minus sign.
151- * </p>
152- *
153- * @param convertDimension if {@code true}, the output will be the
154- * {@code value * dimensionFactor}
155- * @return a nice {@code String} representing the {@code value} of this
156- * {@code NumericProperty} and its {@code error}
157- */
158-
159- public static String formattedValueAndError (NumericProperty p , boolean convertDimension ) {
160-
161- if (p .getValue () instanceof Integer ) {
162- Number val = convertDimension ? ((Number ) p .getValue ()).intValue () * p .getDimensionFactor ().intValue ()
163- : ((Number ) p .getValue ()).intValue ();
164- return (NumberFormat .getIntegerInstance ()).format (val );
165- }
166-
167- final String PLUS_MINUS = Messages .getString ("NumericProperty.PlusMinus" );
168-
169- final double UPPER_LIMIT = 1e4 ; // the upper limit, used for formatting
170- final double LOWER_LIMIT = 1e-2 ; // the lower limit, used for formatting
171- final double ZERO = 1e-30 ;
172-
173- double adjustedValue = convertDimension ? p .valueInCurrentUnits ().doubleValue () : (double ) p .getValue ();
174-
175- double absAdjustedValue = Math .abs (adjustedValue );
176-
177- DecimalFormat selectedFormat = null ;
178-
179- if ((absAdjustedValue > UPPER_LIMIT ) || (absAdjustedValue < LOWER_LIMIT && absAdjustedValue > ZERO ))
180- selectedFormat = new DecimalFormat (Messages .getString ("NumericProperty.BigNumberFormat" ));
181- else
182- selectedFormat = new DecimalFormat (Messages .getString ("NumericProperty.NumberFormat" ));
183-
184- if (p .getError () != null )
185- return selectedFormat .format (adjustedValue ) + PLUS_MINUS
186- + selectedFormat
187- .format (convertDimension ? (double ) p .getError () * p .getDimensionFactor ().doubleValue ()
188- : (double ) p .getError ());
189- else
190- return selectedFormat .format (adjustedValue );
191-
192- }
193-
194- public static boolean isDiscrete (NumericPropertyKeyword key ) {
195- return def (key ).isDiscrete ();
196- }
197-
198- }
16+ /**
17+ * The list of default properties read that is created by reading the
18+ * default {@code .xml} file.
19+ */
20+ private final static List <NumericProperty > DEFAULT = XMLConverter .readDefaultXML ();
21+
22+ private NumericProperties () {
23+ //empty constructor
24+ }
25+
26+ /**
27+ * Checks whether the {@code val} that is going to be passed to the
28+ * {@code property} (a) has the same type as the {@code property.getValue()}
29+ * object; (b) is confined within the definition domain:
30+ * {@code minimum <= value <= maximum}.
31+ *
32+ * @param property the {@code property} containing the definition domain
33+ * @param val a numeric value, the conformity of which to the definition
34+ * domain needs to be checked
35+ * @return {@code true} if {@code minimum <= val <= maximum} and if both
36+ * {@code val} and {@code value} are instances of the same {@code class};
37+ * {@code false} otherwise
38+ */
39+ public static boolean isValueSensible (NumericProperty property , Number val ) {
40+ if (!property .getValue ().getClass ().equals (val .getClass ())) {
41+ return false ;
42+ }
43+
44+ double v = val .doubleValue ();
45+
46+ final double EPS = 1E-12 ;
47+
48+ if (v > property .getMaximum ().doubleValue () + EPS ) {
49+ return false ;
50+ }
51+
52+ return v >= property .getMinimum ().doubleValue () - EPS ;
53+
54+ }
55+
56+ public static String printRangeAndNumber (NumericProperty p , Number value ) {
57+ StringBuilder msg = new StringBuilder ();
58+ msg .append ("Acceptable region for " );
59+ msg .append ("parameter : " );
60+ msg .append (p .getValue ().getClass ().getSimpleName ());
61+ msg .append (" [ " + p .getMinimum ());
62+ msg .append (" : " + p .getMaximum () + " ]. " );
63+ msg .append ("Value received: " + value );
64+ return msg .toString ();
65+ }
66+
67+ public static List <NumericProperty > defaultList () {
68+ return DEFAULT ;
69+ }
70+
71+ /**
72+ * Searches for the default {@code NumericProperty} corresponding to
73+ * {@code keyword} in the list of pre-defined properties loaded from the
74+ * respective {@code .xml} file.
75+ *
76+ * @param keyword one of the constant {@code NumericPropertyKeyword}s
77+ * @return a {@code NumericProperty} in the default list of properties
78+ * @see pulse.properties.NumericPropertyKeyword
79+ */
80+ public static NumericProperty def (NumericPropertyKeyword keyword ) {
81+ return new NumericProperty (DEFAULT .stream ().filter (p -> p .getType () == keyword ).findFirst ().get ());
82+ }
83+
84+ /**
85+ * Compares the numeric values of this {@code NumericProperty} and
86+ * {@code arg0}
87+ *
88+ * @param a a {@code NumericProperty}
89+ * @param b another {@code NumericProperty}
90+ * @return {@code true} if the values are equals
91+ */
92+ public static int compare (NumericProperty a , NumericProperty b ) {
93+ Double d1 = ((Number ) a .getValue ()).doubleValue ();
94+ Double d2 = ((Number ) b .getValue ()).doubleValue ();
95+
96+ final double eps = 1E-8 * (d1 + d2 ) / 2.0 ;
97+
98+ return Math .abs (d1 - d2 ) < eps ? 0 : d1 .compareTo (d2 );
99+ }
100+
101+ /**
102+ * Searches for the default {@code NumericProperty} corresponding to
103+ * {@code keyword} in the list of pre-defined properties loaded from the
104+ * respective {@code .xml} file, and if found creates a new
105+ * {@NumericProperty} which will replicate all field of the latter, but will
106+ * set its value to {@code value}.
107+ *
108+ * @param keyword one of the constant {@code NumericPropertyKeyword}s
109+ * @param value the new value for the created {@code NumericProperty}
110+ * @return a new {@code NumericProperty} that is built according to the
111+ * default pattern specified by the {@code keyword}, but with a different
112+ * {@code value}
113+ * @see pulse.properties.NumericPropertyKeyword
114+ */
115+ public static NumericProperty derive (NumericPropertyKeyword keyword , Number value ) {
116+ return new NumericProperty (value , DEFAULT .stream ().filter (p -> p .getType () == keyword ).findFirst ().get ());
117+ }
118+
119+ public static boolean isDiscrete (NumericPropertyKeyword key ) {
120+ return def (key ).isDiscrete ();
121+ }
122+
123+ }
0 commit comments