001: package net.sf.saxon.exslt;
002:
003: import net.sf.saxon.expr.XPathContext;
004: import net.sf.saxon.om.Item;
005: import net.sf.saxon.om.SequenceIterator;
006: import net.sf.saxon.trans.DynamicError;
007: import net.sf.saxon.trans.XPathException;
008: import net.sf.saxon.value.EmptySequence;
009: import net.sf.saxon.value.SequenceExtent;
010: import net.sf.saxon.value.Value;
011:
012: import java.util.ArrayList;
013:
014: /**
015: * This class implements extension functions in the
016: * http://exslt.org/math namespace. <p>
017: */
018:
019: public abstract class Math {
020:
021: /**
022: * Get the maximum numeric value of the string-value of each of a set of nodes
023: */
024:
025: public static double max(SequenceIterator nsv)
026: throws XPathException {
027: double max = Double.NEGATIVE_INFINITY;
028: try {
029: while (true) {
030: Item it = nsv.next();
031: if (it == null)
032: break;
033: double x = Value.stringToNumber(it.getStringValueCS());
034: if (Double.isNaN(x))
035: return x;
036: if (x > max)
037: max = x;
038: }
039: return max;
040: } catch (NumberFormatException err) {
041: return Double.NaN;
042: }
043: }
044:
045: /**
046: * Get the minimum numeric value of the string-value of each of a set of nodes
047: */
048:
049: public static double min(SequenceIterator nsv)
050: throws XPathException {
051: try {
052: double min = Double.POSITIVE_INFINITY;
053: while (true) {
054: Item it = nsv.next();
055: if (it == null)
056: break;
057: double x = Value.stringToNumber(it.getStringValueCS());
058: if (Double.isNaN(x))
059: return x;
060: if (x < min)
061: min = x;
062: }
063: return min;
064: } catch (NumberFormatException e) {
065: return Double.NaN;
066: }
067: }
068:
069: /**
070: * Get the items with maximum numeric value of the string-value of each of a sequence of items.
071: * The items are returned in the order of the original sequence.
072: */
073:
074: public static Value highest(SequenceIterator nsv)
075: throws XPathException {
076: try {
077: double max = Double.NEGATIVE_INFINITY;
078: ArrayList highest = new ArrayList();
079: while (true) {
080: Item it = nsv.next();
081: if (it == null)
082: break;
083: double x = Value.stringToNumber(it.getStringValueCS());
084: if (Double.isNaN(x))
085: return EmptySequence.getInstance();
086: if (x == max) {
087: highest.add(it);
088: } else if (x > max) {
089: max = x;
090: highest.clear();
091: highest.add(it);
092: }
093: }
094: return new SequenceExtent(highest);
095: } catch (NumberFormatException e) {
096: return EmptySequence.getInstance();
097: }
098: }
099:
100: /**
101: * Get the items with minimum numeric value of the string-value of each of a sequence of items
102: * The items are returned in the order of the original sequence.
103: */
104:
105: public static Value lowest(SequenceIterator nsv)
106: throws XPathException {
107: try {
108: double min = Double.POSITIVE_INFINITY;
109: ArrayList lowest = new ArrayList();
110: while (true) {
111: Item it = nsv.next();
112: if (it == null)
113: break;
114: double x = Value.stringToNumber(it.getStringValueCS());
115: if (Double.isNaN(x))
116: return EmptySequence.getInstance();
117: if (x == min) {
118: lowest.add(it);
119: } else if (x < min) {
120: min = x;
121: lowest.clear();
122: lowest.add(it);
123: }
124: }
125: return new SequenceExtent(lowest);
126: } catch (NumberFormatException e) {
127: return EmptySequence.getInstance();
128: }
129: }
130:
131: /**
132: * Get the absolute value of a numeric value (SStL)
133: */
134:
135: public static double abs(double x) {
136: return java.lang.Math.abs(x);
137: }
138:
139: /**
140: * Get the square root of a numeric value (SStL)
141: */
142:
143: public static double sqrt(double x) {
144: return java.lang.Math.sqrt(x);
145: }
146:
147: /**
148: * Get the power of two numeric values (SStL)
149: */
150:
151: public static double power(double x, double y) {
152: return java.lang.Math.pow(x, y);
153: }
154:
155: /**
156: * Get a named constant to a given precision (SStL)
157: */
158:
159: public static double constant(XPathContext context, String name,
160: double precision) throws XPathException {
161: //PI, E, SQRRT2, LN2, LN10, LOG2E, SQRT1_2
162:
163: String con = "";
164:
165: if (name.equals("PI")) {
166: con = "3.1415926535897932384626433832795028841971693993751";
167: } else if (name.equals("E")) {
168: con = "2.71828182845904523536028747135266249775724709369996";
169: } else if (name.equals("SQRRT2")) {
170: con = "1.41421356237309504880168872420969807856967187537694";
171: } else if (name.equals("LN2")) {
172: con = "0.69314718055994530941723212145817656807550013436025";
173: } else if (name.equals("LN10")) {
174: con = "2.302585092994046";
175: } else if (name.equals("LOG2E")) {
176: con = "1.4426950408889633";
177: } else if (name.equals("SQRT1_2")) {
178: con = "0.7071067811865476";
179: } else {
180: DynamicError e = new DynamicError("Unknown math constant "
181: + name);
182: e.setXPathContext(context);
183: throw e;
184: }
185:
186: int x = (int) precision;
187: String returnVal = con.substring(0, x + 2);
188: double rV = new Double(returnVal).doubleValue();
189: return rV;
190: }
191:
192: /**
193: * Get the logarithm of a numeric value (SStL)
194: */
195:
196: public static double log(double x) {
197: return java.lang.Math.log(x);
198: }
199:
200: /**
201: * Get a random numeric value (SStL)
202: */
203:
204: public static double random() {
205: return java.lang.Math.random();
206: }
207:
208: /**
209: * Get the sine of a numeric value (SStL)
210: */
211:
212: public static double sin(double x) {
213: return java.lang.Math.sin(x);
214: }
215:
216: /**
217: * Get the cosine of a numeric value (SStL)
218: */
219:
220: public static double cos(double x) {
221: return java.lang.Math.cos(x);
222: }
223:
224: /**
225: * Get the tangent of a numeric value (SStL)
226: */
227:
228: public static double tan(double x) {
229: return java.lang.Math.tan(x);
230: }
231:
232: /**
233: * Get the arcsine of a numeric value (SStL)
234: */
235:
236: public static double asin(double x) {
237: return java.lang.Math.asin(x);
238: }
239:
240: /**
241: * Get the arccosine of a numeric value (SStL)
242: */
243:
244: public static double acos(double x) {
245: return java.lang.Math.acos(x);
246: }
247:
248: /**
249: * Get the arctangent of a numeric value (SStL)
250: */
251:
252: public static double atan(double x) {
253: return java.lang.Math.atan(x);
254: }
255:
256: /**
257: * Converts rectangular coordinates to polar (SStL)
258: */
259:
260: public static double atan2(double x, double y) {
261: return java.lang.Math.atan2(x, y);
262: }
263:
264: /**
265: * Get the exponential of a numeric value (SStL)
266: */
267:
268: public static double exp(double x) {
269: return java.lang.Math.exp(x);
270: }
271:
272: }
273:
274: //
275: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
276: // you may not use this file except in compliance with the License. You may obtain a copy of the
277: // License at http://www.mozilla.org/MPL/
278: //
279: // Software distributed under the License is distributed on an "AS IS" basis,
280: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
281: // See the License for the specific language governing rights and limitations under the License.
282: //
283: // The Original Code is: all this file.
284: //
285: // The Initial Developer of the Original Code is Michael H. Kay.
286: //
287: // Portions marked SStL were provided by Simon St.Laurent [simonstl@simonstl.com]. All Rights Reserved.
288: //
289: // Contributor(s): none.
290: //
|