1 | /*
|
---|
2 | * This program is free software; you can redistribute it and/or modify
|
---|
3 | * it under the terms of the GNU General Public License as published by
|
---|
4 | * the Free Software Foundation; either version 2 of the License, or
|
---|
5 | * (at your option) any later version.
|
---|
6 | *
|
---|
7 | * This program is distributed in the hope that it will be useful,
|
---|
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
10 | * GNU General Public License for more details.
|
---|
11 | *
|
---|
12 | * You should have received a copy of the GNU General Public License
|
---|
13 | * along with this program; if not, write to the Free Software
|
---|
14 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
---|
15 | */
|
---|
16 |
|
---|
17 | /*
|
---|
18 | * Utils.java
|
---|
19 | * Copyright (C) 1999 Eibe Frank,Len Trigg,Yong Wang
|
---|
20 | *
|
---|
21 | */
|
---|
22 |
|
---|
23 | package weka.core;
|
---|
24 |
|
---|
25 | import java.lang.Math;
|
---|
26 | import java.util.StringTokenizer;
|
---|
27 | import java.util.Properties;
|
---|
28 | import java.io.File;
|
---|
29 | import java.io.FileInputStream;
|
---|
30 |
|
---|
31 | /**
|
---|
32 | * Class implementing some simple utility methods.
|
---|
33 | *
|
---|
34 | * @author Eibe Frank ([email protected])
|
---|
35 | * @author Yong Wang ([email protected])
|
---|
36 | * @author Len Trigg ([email protected])
|
---|
37 | * @version $Revision: 8815 $
|
---|
38 | */
|
---|
39 | public final class Utils {
|
---|
40 |
|
---|
41 | /** The natural logarithm of 2. */
|
---|
42 | public static double log2 = Math.log(2);
|
---|
43 |
|
---|
44 | /** The small deviation allowed in double comparisons */
|
---|
45 | public static double SMALL = 1e-6;
|
---|
46 |
|
---|
47 |
|
---|
48 | /**
|
---|
49 | * Reads properties that inherit from three locations. Properties
|
---|
50 | * are first defined in the system resource location (i.e. in the
|
---|
51 | * CLASSPATH). These default properties must exist. Properties
|
---|
52 | * defined in the users home directory (optional) override default
|
---|
53 | * settings. Properties defined in the current directory (optional)
|
---|
54 | * override all these settings.
|
---|
55 | *
|
---|
56 | * @param resourceName the location of the resource that should be
|
---|
57 | * loaded. e.g.: "weka/core/Utils.props". (The use of hardcoded
|
---|
58 | * forward slashes here is OK - see
|
---|
59 | * jdk1.1/docs/guide/misc/resources.html) This routine will also
|
---|
60 | * look for the file (in this case) "Utils.props" in the users home
|
---|
61 | * directory and the current directory.
|
---|
62 | * @return the Properties
|
---|
63 | * @exception Exception if no default properties are defined, or if
|
---|
64 | * an error occurs reading the properties files.
|
---|
65 | */
|
---|
66 | public static Properties readProperties(String resourceName)
|
---|
67 | throws Exception{
|
---|
68 |
|
---|
69 | Properties defaultProps = new Properties();
|
---|
70 | try {
|
---|
71 | // Apparently hardcoded slashes are OK here
|
---|
72 | // jdk1.1/docs/guide/misc/resources.html
|
---|
73 | defaultProps.load(ClassLoader.getSystemResourceAsStream(resourceName));
|
---|
74 | } catch (Exception ex) {
|
---|
75 | /* throw new Exception("Problem reading default properties: "
|
---|
76 | + ex.getMessage()); */
|
---|
77 | System.err.println("Warning, unable to load properties file from "
|
---|
78 | +"system resource (Utils.java)");
|
---|
79 | }
|
---|
80 |
|
---|
81 | // Hardcoded slash is OK here
|
---|
82 | // eg: see jdk1.1/docs/guide/misc/resources.html
|
---|
83 | int slInd = resourceName.lastIndexOf('/');
|
---|
84 | if (slInd != -1) {
|
---|
85 | resourceName = resourceName.substring(slInd + 1);
|
---|
86 | }
|
---|
87 |
|
---|
88 | // Allow a properties file in the home directory to override
|
---|
89 | Properties userProps = new Properties(defaultProps);
|
---|
90 | File propFile = new File(System.getProperties().getProperty("user.home")
|
---|
91 | + File.separatorChar
|
---|
92 | + resourceName);
|
---|
93 | if (propFile.exists()) {
|
---|
94 | try {
|
---|
95 | userProps.load(new FileInputStream(propFile));
|
---|
96 | } catch (Exception ex) {
|
---|
97 | throw new Exception("Problem reading user properties: " + propFile);
|
---|
98 | }
|
---|
99 | }
|
---|
100 |
|
---|
101 | // Allow a properties file in the current directory to override
|
---|
102 | Properties localProps = new Properties(userProps);
|
---|
103 | propFile = new File(resourceName);
|
---|
104 | if (propFile.exists()) {
|
---|
105 | try {
|
---|
106 | localProps.load(new FileInputStream(propFile));
|
---|
107 | } catch (Exception ex) {
|
---|
108 | throw new Exception("Problem reading local properties: " + propFile);
|
---|
109 | }
|
---|
110 | }
|
---|
111 |
|
---|
112 | return localProps;
|
---|
113 | }
|
---|
114 |
|
---|
115 | /**
|
---|
116 | * Returns the correlation coefficient of two double vectors.
|
---|
117 | *
|
---|
118 | * @param y1 double vector 1
|
---|
119 | * @param y2 double vector 2
|
---|
120 | * @param n the length of two double vectors
|
---|
121 | * @return the correlation coefficient
|
---|
122 | */
|
---|
123 | public final static double correlation(double y1[],double y2[],int n) {
|
---|
124 |
|
---|
125 | int i;
|
---|
126 | double av1 = 0.0, av2 = 0.0, y11 = 0.0, y22 = 0.0, y12 = 0.0, c;
|
---|
127 |
|
---|
128 | if (n <= 1) {
|
---|
129 | return 1.0;
|
---|
130 | }
|
---|
131 | for (i = 0; i < n; i++) {
|
---|
132 | av1 += y1[i];
|
---|
133 | av2 += y2[i];
|
---|
134 | }
|
---|
135 | av1 /= (double) n;
|
---|
136 | av2 /= (double) n;
|
---|
137 | for (i = 0; i < n; i++) {
|
---|
138 | y11 += (y1[i] - av1) * (y1[i] - av1);
|
---|
139 | y22 += (y2[i] - av2) * (y2[i] - av2);
|
---|
140 | y12 += (y1[i] - av1) * (y2[i] - av2);
|
---|
141 | }
|
---|
142 | if (y11 * y22 == 0.0) {
|
---|
143 | c=1.0;
|
---|
144 | } else {
|
---|
145 | c = y12 / Math.sqrt(Math.abs(y11 * y22));
|
---|
146 | }
|
---|
147 |
|
---|
148 | return c;
|
---|
149 | }
|
---|
150 |
|
---|
151 | /**
|
---|
152 | * Removes all occurrences of a string from another string.
|
---|
153 | *
|
---|
154 | * @param inString the string to remove substrings from.
|
---|
155 | * @param substring the substring to remove.
|
---|
156 | * @return the input string with occurrences of substring removed.
|
---|
157 | */
|
---|
158 | public static String removeSubstring(String inString, String substring) {
|
---|
159 |
|
---|
160 | StringBuffer result = new StringBuffer();
|
---|
161 | int oldLoc = 0, loc = 0;
|
---|
162 | while ((loc = inString.indexOf(substring, oldLoc))!= -1) {
|
---|
163 | result.append(inString.substring(oldLoc, loc));
|
---|
164 | oldLoc = loc + substring.length();
|
---|
165 | }
|
---|
166 | result.append(inString.substring(oldLoc));
|
---|
167 | return result.toString();
|
---|
168 | }
|
---|
169 |
|
---|
170 | /**
|
---|
171 | * Replaces with a new string, all occurrences of a string from
|
---|
172 | * another string.
|
---|
173 | *
|
---|
174 | * @param inString the string to replace substrings in.
|
---|
175 | * @param substring the substring to replace.
|
---|
176 | * @param replaceString the replacement substring
|
---|
177 | * @return the input string with occurrences of substring replaced.
|
---|
178 | */
|
---|
179 | public static String replaceSubstring(String inString, String subString,
|
---|
180 | String replaceString) {
|
---|
181 |
|
---|
182 | StringBuffer result = new StringBuffer();
|
---|
183 | int oldLoc = 0, loc = 0;
|
---|
184 | while ((loc = inString.indexOf(subString, oldLoc))!= -1) {
|
---|
185 | result.append(inString.substring(oldLoc, loc));
|
---|
186 | result.append(replaceString);
|
---|
187 | oldLoc = loc + subString.length();
|
---|
188 | }
|
---|
189 | result.append(inString.substring(oldLoc));
|
---|
190 | return result.toString();
|
---|
191 | }
|
---|
192 |
|
---|
193 |
|
---|
194 | /**
|
---|
195 | * Pads a string to a specified length, inserting spaces on the left
|
---|
196 | * as required. If the string is too long, characters are removed (from
|
---|
197 | * the right).
|
---|
198 | *
|
---|
199 | * @param inString the input string
|
---|
200 | * @param length the desired length of the output string
|
---|
201 | * @return the output string
|
---|
202 | */
|
---|
203 | public static String padLeft(String inString, int length) {
|
---|
204 |
|
---|
205 | return fixStringLength(inString, length, false);
|
---|
206 | }
|
---|
207 |
|
---|
208 | /**
|
---|
209 | * Pads a string to a specified length, inserting spaces on the right
|
---|
210 | * as required. If the string is too long, characters are removed (from
|
---|
211 | * the right).
|
---|
212 | *
|
---|
213 | * @param inString the input string
|
---|
214 | * @param length the desired length of the output string
|
---|
215 | * @return the output string
|
---|
216 | */
|
---|
217 | public static String padRight(String inString, int length) {
|
---|
218 |
|
---|
219 | return fixStringLength(inString, length, true);
|
---|
220 | }
|
---|
221 |
|
---|
222 | /**
|
---|
223 | * Pads a string to a specified length, inserting spaces as
|
---|
224 | * required. If the string is too long, characters are removed (from
|
---|
225 | * the right).
|
---|
226 | *
|
---|
227 | * @param inString the input string
|
---|
228 | * @param length the desired length of the output string
|
---|
229 | * @param right true if inserted spaces should be added to the right
|
---|
230 | * @return the output string
|
---|
231 | */
|
---|
232 | private static String fixStringLength(String inString, int length,
|
---|
233 | boolean right) {
|
---|
234 |
|
---|
235 | if (inString.length() < length) {
|
---|
236 | while (inString.length() < length) {
|
---|
237 | inString = (right ? inString.concat(" ") : " ".concat(inString));
|
---|
238 | }
|
---|
239 | } else if (inString.length() > length) {
|
---|
240 | inString = inString.substring(0, length);
|
---|
241 | }
|
---|
242 | return inString;
|
---|
243 | }
|
---|
244 |
|
---|
245 | /**
|
---|
246 | * Rounds a double and converts it into String.
|
---|
247 | *
|
---|
248 | * @param value the double value
|
---|
249 | * @param afterDecimalPoint the (maximum) number of digits permitted
|
---|
250 | * after the decimal point
|
---|
251 | * @return the double as a formatted string
|
---|
252 | */
|
---|
253 | public static String doubleToString(double value, int afterDecimalPoint) {
|
---|
254 |
|
---|
255 | StringBuffer stringBuffer;
|
---|
256 | double temp;
|
---|
257 | int i,dotPosition;
|
---|
258 | long precisionValue;
|
---|
259 |
|
---|
260 | temp = value * Math.pow(10.0, afterDecimalPoint);
|
---|
261 | if (Math.abs(temp) < Long.MAX_VALUE) {
|
---|
262 | precisionValue = (temp > 0) ? (long)(temp + 0.5)
|
---|
263 | : -(long)(Math.abs(temp) + 0.5);
|
---|
264 | if (precisionValue == 0) {
|
---|
265 | stringBuffer = new StringBuffer(String.valueOf(0));
|
---|
266 | } else {
|
---|
267 | stringBuffer = new StringBuffer(String.valueOf(precisionValue));
|
---|
268 | }
|
---|
269 | if (afterDecimalPoint == 0) {
|
---|
270 | return stringBuffer.toString();
|
---|
271 | }
|
---|
272 | dotPosition = stringBuffer.length() - afterDecimalPoint;
|
---|
273 | while (((precisionValue < 0) && (dotPosition < 1)) ||
|
---|
274 | (dotPosition < 0)) {
|
---|
275 | if (precisionValue < 0) {
|
---|
276 | stringBuffer.insert(1, 0);
|
---|
277 | } else {
|
---|
278 | stringBuffer.insert(0, 0);
|
---|
279 | }
|
---|
280 | dotPosition++;
|
---|
281 | }
|
---|
282 | stringBuffer.insert(dotPosition, '.');
|
---|
283 | if ((precisionValue < 0) && (stringBuffer.charAt(1) == '.')) {
|
---|
284 | stringBuffer.insert(1, 0);
|
---|
285 | } else if (stringBuffer.charAt(0) == '.') {
|
---|
286 | stringBuffer.insert(0, 0);
|
---|
287 | }
|
---|
288 | int currentPos = stringBuffer.length() - 1;
|
---|
289 | while ((currentPos > dotPosition) &&
|
---|
290 | (stringBuffer.charAt(currentPos) == '0')) {
|
---|
291 | stringBuffer.setCharAt(currentPos--, ' ');
|
---|
292 | }
|
---|
293 | if (stringBuffer.charAt(currentPos) == '.') {
|
---|
294 | stringBuffer.setCharAt(currentPos, ' ');
|
---|
295 | }
|
---|
296 |
|
---|
297 | return stringBuffer.toString().trim();
|
---|
298 | }
|
---|
299 | return new String("" + value);
|
---|
300 | }
|
---|
301 |
|
---|
302 | /**
|
---|
303 | * Rounds a double and converts it into a formatted decimal-justified String.
|
---|
304 | * Trailing 0's are replaced with spaces.
|
---|
305 | *
|
---|
306 | * @param value the double value
|
---|
307 | * @param width the width of the string
|
---|
308 | * @param afterDecimalPoint the number of digits after the decimal point
|
---|
309 | * @return the double as a formatted string
|
---|
310 | */
|
---|
311 | public static String doubleToString(double value, int width,
|
---|
312 | int afterDecimalPoint) {
|
---|
313 |
|
---|
314 | String tempString = doubleToString(value, afterDecimalPoint);
|
---|
315 | char[] result;
|
---|
316 | int dotPosition;
|
---|
317 |
|
---|
318 | if ((afterDecimalPoint >= width)
|
---|
319 | || (tempString.indexOf('E') != -1)) { // Protects sci notation
|
---|
320 | return tempString;
|
---|
321 | }
|
---|
322 |
|
---|
323 | // Initialize result
|
---|
324 | result = new char[width];
|
---|
325 | for (int i = 0; i < result.length; i++) {
|
---|
326 | result[i] = ' ';
|
---|
327 | }
|
---|
328 |
|
---|
329 | if (afterDecimalPoint > 0) {
|
---|
330 | // Get position of decimal point and insert decimal point
|
---|
331 | dotPosition = tempString.indexOf('.');
|
---|
332 | if (dotPosition == -1) {
|
---|
333 | dotPosition = tempString.length();
|
---|
334 | } else {
|
---|
335 | result[width - afterDecimalPoint - 1] = '.';
|
---|
336 | }
|
---|
337 | } else {
|
---|
338 | dotPosition = tempString.length();
|
---|
339 | }
|
---|
340 |
|
---|
341 |
|
---|
342 | int offset = width - afterDecimalPoint - dotPosition;
|
---|
343 | if (afterDecimalPoint > 0) {
|
---|
344 | offset--;
|
---|
345 | }
|
---|
346 |
|
---|
347 | // Not enough room to decimal align within the supplied width
|
---|
348 | if (offset < 0) {
|
---|
349 | return tempString;
|
---|
350 | }
|
---|
351 |
|
---|
352 | // Copy characters before decimal point
|
---|
353 | for (int i = 0; i < dotPosition; i++) {
|
---|
354 | result[offset + i] = tempString.charAt(i);
|
---|
355 | }
|
---|
356 |
|
---|
357 | // Copy characters after decimal point
|
---|
358 | for (int i = dotPosition + 1; i < tempString.length(); i++) {
|
---|
359 | result[offset + i] = tempString.charAt(i);
|
---|
360 | }
|
---|
361 |
|
---|
362 | return new String(result);
|
---|
363 | }
|
---|
364 |
|
---|
365 | /**
|
---|
366 | * Tests if a is equal to b.
|
---|
367 | *
|
---|
368 | * @param a a double
|
---|
369 | * @param b a double
|
---|
370 | */
|
---|
371 | public static boolean eq(double a, double b){
|
---|
372 |
|
---|
373 | return (a - b < SMALL) && (b - a < SMALL);
|
---|
374 | }
|
---|
375 |
|
---|
376 | /**
|
---|
377 | * Checks if the given array contains any non-empty options.
|
---|
378 | *
|
---|
379 | * @param strings an array of strings
|
---|
380 | * @exception Exception if there are any non-empty options
|
---|
381 | */
|
---|
382 | public static void checkForRemainingOptions(String [] options)
|
---|
383 | throws Exception {
|
---|
384 |
|
---|
385 | int illegalOptionsFound = 0;
|
---|
386 | StringBuffer text = new StringBuffer();
|
---|
387 |
|
---|
388 | if (options == null) {
|
---|
389 | return;
|
---|
390 | }
|
---|
391 | for (int i = 0; i < options.length; i++) {
|
---|
392 | if (options[i].length() > 0) {
|
---|
393 | illegalOptionsFound++;
|
---|
394 | text.append(options[i] + ' ');
|
---|
395 | }
|
---|
396 | }
|
---|
397 | if (illegalOptionsFound > 0) {
|
---|
398 | throw new Exception("Illegal options: " + text);
|
---|
399 | }
|
---|
400 | }
|
---|
401 |
|
---|
402 | /**
|
---|
403 | * Checks if the given array contains the flag "-Char". Stops
|
---|
404 | * searching at the first marker "--". If the flag is found,
|
---|
405 | * it is replaced with the empty string.
|
---|
406 | *
|
---|
407 | * @param flag the character indicating the flag.
|
---|
408 | * @param strings the array of strings containing all the options.
|
---|
409 | * @return true if the flag was found
|
---|
410 | * @exception Exception if an illegal option was found
|
---|
411 | */
|
---|
412 |
|
---|
413 | public static boolean getFlag(char flag, String [] options)
|
---|
414 | throws Exception {
|
---|
415 |
|
---|
416 | if (options == null) {
|
---|
417 | return false;
|
---|
418 | }
|
---|
419 | for (int i = 0; i < options.length; i++) {
|
---|
420 | if ((options[i].length() > 1) && (options[i].charAt(0) == '-')) {
|
---|
421 | try {
|
---|
422 | Double dummy = Double.valueOf(options[i]);
|
---|
423 | } catch (NumberFormatException e) {
|
---|
424 | if (options[i].length() > 2) {
|
---|
425 | throw new Exception("Illegal option: " + options[i]);
|
---|
426 | }
|
---|
427 | if (options[i].charAt(1) == flag) {
|
---|
428 | options[i] = "";
|
---|
429 | return true;
|
---|
430 | }
|
---|
431 | if (options[i].charAt(1) == '-') {
|
---|
432 | return false;
|
---|
433 | }
|
---|
434 | }
|
---|
435 | }
|
---|
436 | }
|
---|
437 | return false;
|
---|
438 | }
|
---|
439 |
|
---|
440 | /**
|
---|
441 | * Gets an option indicated by a flag "-Char" from the given array
|
---|
442 | * of strings. Stops searching at the first marker "--". Replaces
|
---|
443 | * flag and option with empty strings.
|
---|
444 | *
|
---|
445 | * @param flag the character indicating the option.
|
---|
446 | * @param options the array of strings containing all the options.
|
---|
447 | * @return the indicated option or an empty string
|
---|
448 | * @exception Exception if the option indicated by the flag can't be found
|
---|
449 | */
|
---|
450 | public static String getOption(char flag, String [] options)
|
---|
451 | throws Exception {
|
---|
452 |
|
---|
453 | String newString;
|
---|
454 |
|
---|
455 | if (options == null)
|
---|
456 | return "";
|
---|
457 | for (int i = 0; i < options.length; i++) {
|
---|
458 | if ((options[i].length() > 0) && (options[i].charAt(0) == '-')) {
|
---|
459 |
|
---|
460 | // Check if it is a negative number
|
---|
461 | try {
|
---|
462 | Double dummy = Double.valueOf(options[i]);
|
---|
463 | } catch (NumberFormatException e) {
|
---|
464 | if (options[i].length() > 2) {
|
---|
465 | throw new Exception("Illegal option: " + options[i]);
|
---|
466 | }
|
---|
467 | if (options[i].charAt(1) == flag) {
|
---|
468 | if (i + 1 == options.length) {
|
---|
469 | throw new Exception("No value given for -" + flag + " option.");
|
---|
470 | }
|
---|
471 | options[i] = "";
|
---|
472 | newString = new String(options[i + 1]);
|
---|
473 | options[i + 1] = "";
|
---|
474 | return newString;
|
---|
475 | }
|
---|
476 | if (options[i].charAt(1) == '-') {
|
---|
477 | return "";
|
---|
478 | }
|
---|
479 | }
|
---|
480 | }
|
---|
481 | }
|
---|
482 | return "";
|
---|
483 | }
|
---|
484 |
|
---|
485 | /**
|
---|
486 | * Quotes a string if it contains special characters.
|
---|
487 | *
|
---|
488 | * The following rules are applied:
|
---|
489 | *
|
---|
490 | * A character is backquoted version of it is one
|
---|
491 | * of <tt>" ' % \ \n \r \t</tt>.
|
---|
492 | *
|
---|
493 | * A string is enclosed within single quotes if a character has been
|
---|
494 | * backquoted using the previous rule above or contains
|
---|
495 | * <tt>{ }</tt> or is exactly equal to the strings
|
---|
496 | * <tt>, ? space or ""</tt> (empty string).
|
---|
497 | *
|
---|
498 | * A quoted question mark distinguishes it from the missing value which
|
---|
499 | * is represented as an unquoted question mark in arff files.
|
---|
500 | *
|
---|
501 | * @param string the string to be quoted
|
---|
502 | * @return the string (possibly quoted)
|
---|
503 | */
|
---|
504 | public static String quote(String string) {
|
---|
505 | boolean quote = false;
|
---|
506 |
|
---|
507 | // backquote the following characters
|
---|
508 | if ((string.indexOf('\n') != -1) || (string.indexOf('\r') != -1) ||
|
---|
509 | (string.indexOf('\'') != -1) || (string.indexOf('"') != -1) ||
|
---|
510 | (string.indexOf('\\') != -1) ||
|
---|
511 | (string.indexOf('\t') != -1) || (string.indexOf('%') != -1)) {
|
---|
512 | string = backQuoteChars(string);
|
---|
513 | quote = true;
|
---|
514 | }
|
---|
515 |
|
---|
516 | // Enclose the string in 's if the string contains a recently added
|
---|
517 | // backquote or contains one of the following characters.
|
---|
518 | if((quote == true) ||
|
---|
519 | (string.indexOf('{') != -1) || (string.indexOf('}') != -1) ||
|
---|
520 | (string.indexOf(',') != -1) || (string.equals("?")) ||
|
---|
521 | (string.indexOf(' ') != -1) || (string.equals(""))) {
|
---|
522 | string = ("'".concat(string)).concat("'");
|
---|
523 | }
|
---|
524 |
|
---|
525 | return string;
|
---|
526 | }
|
---|
527 |
|
---|
528 | /**
|
---|
529 | * Converts carriage returns and new lines in a string into \r and \n.
|
---|
530 | * Backquotes the following characters: ` " \ \t and %
|
---|
531 | * @param string the string
|
---|
532 | * @return the converted string
|
---|
533 | */
|
---|
534 | public static String backQuoteChars(String string) {
|
---|
535 |
|
---|
536 | int index;
|
---|
537 | StringBuffer newStringBuffer;
|
---|
538 |
|
---|
539 | // replace each of the following characters with the backquoted version
|
---|
540 | char charsFind[] = {'\\', '\'', '\t', '"', '%'};
|
---|
541 | String charsReplace[] = {"\\\\", "\\'", "\\t", "\\\"", "\\%"};
|
---|
542 | for(int i = 0; i < charsFind.length; i++) {
|
---|
543 | if (string.indexOf(charsFind[i]) != -1 ) {
|
---|
544 | newStringBuffer = new StringBuffer();
|
---|
545 | while ((index = string.indexOf(charsFind[i])) != -1) {
|
---|
546 | if (index > 0) {
|
---|
547 | newStringBuffer.append(string.substring(0, index));
|
---|
548 | }
|
---|
549 | newStringBuffer.append(charsReplace[i]);
|
---|
550 | if ((index + 1) < string.length()) {
|
---|
551 | string = string.substring(index + 1);
|
---|
552 | } else {
|
---|
553 | string = "";
|
---|
554 | }
|
---|
555 | }
|
---|
556 | newStringBuffer.append(string);
|
---|
557 | string = newStringBuffer.toString();
|
---|
558 | }
|
---|
559 | }
|
---|
560 |
|
---|
561 | return Utils.convertNewLines(string);
|
---|
562 | }
|
---|
563 |
|
---|
564 | /**
|
---|
565 | * Converts carriage returns and new lines in a string into \r and \n.
|
---|
566 | * @param string the string
|
---|
567 | * @return the converted string
|
---|
568 | */
|
---|
569 | public static String convertNewLines(String string) {
|
---|
570 |
|
---|
571 | int index;
|
---|
572 |
|
---|
573 | // Replace with \n
|
---|
574 | StringBuffer newStringBuffer = new StringBuffer();
|
---|
575 | while ((index = string.indexOf('\n')) != -1) {
|
---|
576 | if (index > 0) {
|
---|
577 | newStringBuffer.append(string.substring(0, index));
|
---|
578 | }
|
---|
579 | newStringBuffer.append('\\');
|
---|
580 | newStringBuffer.append('n');
|
---|
581 | if ((index + 1) < string.length()) {
|
---|
582 | string = string.substring(index + 1);
|
---|
583 | } else {
|
---|
584 | string = "";
|
---|
585 | }
|
---|
586 | }
|
---|
587 | newStringBuffer.append(string);
|
---|
588 | string = newStringBuffer.toString();
|
---|
589 |
|
---|
590 | // Replace with \r
|
---|
591 | newStringBuffer = new StringBuffer();
|
---|
592 | while ((index = string.indexOf('\r')) != -1) {
|
---|
593 | if (index > 0) {
|
---|
594 | newStringBuffer.append(string.substring(0, index));
|
---|
595 | }
|
---|
596 | newStringBuffer.append('\\');
|
---|
597 | newStringBuffer.append('r');
|
---|
598 | if ((index + 1) < string.length()){
|
---|
599 | string = string.substring(index + 1);
|
---|
600 | } else {
|
---|
601 | string = "";
|
---|
602 | }
|
---|
603 | }
|
---|
604 | newStringBuffer.append(string);
|
---|
605 | return newStringBuffer.toString();
|
---|
606 | }
|
---|
607 |
|
---|
608 |
|
---|
609 | /**
|
---|
610 | * Returns the secondary set of options (if any) contained in
|
---|
611 | * the supplied options array. The secondary set is defined to
|
---|
612 | * be any options after the first "--". These options are removed from
|
---|
613 | * the original options array.
|
---|
614 | *
|
---|
615 | * @param options the input array of options
|
---|
616 | * @return the array of secondary options
|
---|
617 | */
|
---|
618 | public static String [] partitionOptions(String [] options) {
|
---|
619 |
|
---|
620 | for (int i = 0; i < options.length; i++) {
|
---|
621 | if (options[i].equals("--")) {
|
---|
622 | options[i++] = "";
|
---|
623 | String [] result = new String [options.length - i];
|
---|
624 | for (int j = i; j < options.length; j++) {
|
---|
625 | result[j - i] = options[j];
|
---|
626 | options[j] = "";
|
---|
627 | }
|
---|
628 | return result;
|
---|
629 | }
|
---|
630 | }
|
---|
631 | return new String [0];
|
---|
632 | }
|
---|
633 |
|
---|
634 | /**
|
---|
635 | * Split up a string containing options into an array of strings,
|
---|
636 | * one for each option.
|
---|
637 | *
|
---|
638 | * @param optionString the string containing the options
|
---|
639 | * @return the array of options
|
---|
640 | */
|
---|
641 | public static String [] splitOptions(String optionString) {
|
---|
642 |
|
---|
643 | FastVector optionsVec = new FastVector();
|
---|
644 | StringTokenizer st = new StringTokenizer(optionString);
|
---|
645 | while (st.hasMoreTokens())
|
---|
646 | optionsVec.addElement(st.nextToken());
|
---|
647 |
|
---|
648 | String [] options = new String[optionsVec.size()];
|
---|
649 | for (int i = 0; i < optionsVec.size(); i++) {
|
---|
650 | options[i] = (String)optionsVec.elementAt(i);
|
---|
651 | }
|
---|
652 | return options;
|
---|
653 | }
|
---|
654 |
|
---|
655 | /**
|
---|
656 | * Joins all the options in an option array into a single string,
|
---|
657 | * as might be used on the command line.
|
---|
658 | *
|
---|
659 | * @param optionArray the array of options
|
---|
660 | * @return the string containing all options.
|
---|
661 | */
|
---|
662 | public static String joinOptions(String [] optionArray) {
|
---|
663 |
|
---|
664 | String optionString = "";
|
---|
665 | for (int i = 0; i < optionArray.length; i++) {
|
---|
666 | if (optionArray[i].equals("")) {
|
---|
667 | continue;
|
---|
668 | }
|
---|
669 | if (optionArray[i].indexOf(' ') != -1) {
|
---|
670 | optionString += '"' + optionArray[i] + '"';
|
---|
671 | } else {
|
---|
672 | optionString += optionArray[i];
|
---|
673 | }
|
---|
674 | optionString += " ";
|
---|
675 | }
|
---|
676 | return optionString.trim();
|
---|
677 | }
|
---|
678 |
|
---|
679 | /**
|
---|
680 | * Creates a new instance of an object given it's class name and
|
---|
681 | * (optional) arguments to pass to it's setOptions method. If the
|
---|
682 | * object implements OptionHandler and the options parameter is
|
---|
683 | * non-null, the object will have it's options set. Example use:<p>
|
---|
684 | *
|
---|
685 | * <code> <pre>
|
---|
686 | * String classifierName = Utils.getOption('W', options);
|
---|
687 | * Classifier c = (Classifier)Utils.forName(Classifier.class,
|
---|
688 | * classifierName,
|
---|
689 | * options);
|
---|
690 | * setClassifier(c);
|
---|
691 | * </pre></code>
|
---|
692 | *
|
---|
693 | * @param classType the class that the instantiated object should
|
---|
694 | * be assignable to -- an exception is thrown if this is not the case
|
---|
695 | * @param className the fully qualified class name of the object
|
---|
696 | * @param options an array of options suitable for passing to setOptions. May
|
---|
697 | * be null. Any options accepted by the object will be removed from the
|
---|
698 | * array.
|
---|
699 | * @return the newly created object, ready for use.
|
---|
700 | * @exception Exception if the class name is invalid, or if the
|
---|
701 | * class is not assignable to the desired class type, or the options
|
---|
702 | * supplied are not acceptable to the object
|
---|
703 | */
|
---|
704 | public static Object forName(Class classType,
|
---|
705 | String className,
|
---|
706 | String [] options) throws Exception {
|
---|
707 |
|
---|
708 | Class c = null;
|
---|
709 | try {
|
---|
710 | c = Class.forName(className);
|
---|
711 | } catch (Exception ex) {
|
---|
712 | throw new Exception("Can't find class called: " + className);
|
---|
713 | }
|
---|
714 | if (!classType.isAssignableFrom(c)) {
|
---|
715 | throw new Exception(classType.getName() + " is not assignable from "
|
---|
716 | + className);
|
---|
717 | }
|
---|
718 | Object o = c.newInstance();
|
---|
719 | if ((o instanceof OptionHandler)
|
---|
720 | && (options != null)) {
|
---|
721 | ((OptionHandler)o).setOptions(options);
|
---|
722 | Utils.checkForRemainingOptions(options);
|
---|
723 | }
|
---|
724 | return o;
|
---|
725 | }
|
---|
726 |
|
---|
727 | /**
|
---|
728 | * Computes entropy for an array of integers.
|
---|
729 | *
|
---|
730 | * @param counts array of counts
|
---|
731 | * @returns - a log2 a - b log2 b - c log2 c + (a+b+c) log2 (a+b+c)
|
---|
732 | * when given array [a b c]
|
---|
733 | */
|
---|
734 | public static double info(int counts[]) {
|
---|
735 |
|
---|
736 | int total = 0; int c;
|
---|
737 | double x = 0;
|
---|
738 | for (int j = 0; j < counts.length; j++) {
|
---|
739 | x -= xlogx(counts[j]);
|
---|
740 | total += counts[j];
|
---|
741 | }
|
---|
742 | return x + xlogx(total);
|
---|
743 | }
|
---|
744 |
|
---|
745 | /**
|
---|
746 | * Tests if a is smaller or equal to b.
|
---|
747 | *
|
---|
748 | * @param a a double
|
---|
749 | * @param b a double
|
---|
750 | */
|
---|
751 | public static boolean smOrEq(double a,double b) {
|
---|
752 |
|
---|
753 | return (a-b < SMALL);
|
---|
754 | }
|
---|
755 |
|
---|
756 | /**
|
---|
757 | * Tests if a is greater or equal to b.
|
---|
758 | *
|
---|
759 | * @param a a double
|
---|
760 | * @param b a double
|
---|
761 | */
|
---|
762 | public static boolean grOrEq(double a,double b) {
|
---|
763 |
|
---|
764 | return (b-a < SMALL);
|
---|
765 | }
|
---|
766 |
|
---|
767 | /**
|
---|
768 | * Tests if a is smaller than b.
|
---|
769 | *
|
---|
770 | * @param a a double
|
---|
771 | * @param b a double
|
---|
772 | */
|
---|
773 | public static boolean sm(double a,double b) {
|
---|
774 |
|
---|
775 | return (b-a > SMALL);
|
---|
776 | }
|
---|
777 |
|
---|
778 | /**
|
---|
779 | * Tests if a is smaller than b.
|
---|
780 | *
|
---|
781 | * @param a a double
|
---|
782 | * @param b a double
|
---|
783 | */
|
---|
784 | public static boolean gr(double a,double b) {
|
---|
785 |
|
---|
786 | return (a-b > SMALL);
|
---|
787 | }
|
---|
788 |
|
---|
789 | /**
|
---|
790 | * Returns the logarithm of a for base 2.
|
---|
791 | *
|
---|
792 | * @param a a double
|
---|
793 | */
|
---|
794 | public static double log2(double a) {
|
---|
795 |
|
---|
796 | return Math.log(a) / log2;
|
---|
797 | }
|
---|
798 |
|
---|
799 | /**
|
---|
800 | * Returns index of maximum element in a given
|
---|
801 | * array of doubles. First maximum is returned.
|
---|
802 | *
|
---|
803 | * @param doubles the array of doubles
|
---|
804 | * @return the index of the maximum element
|
---|
805 | */
|
---|
806 | public static int maxIndex(double [] doubles) {
|
---|
807 |
|
---|
808 | double maximum = 0;
|
---|
809 | int maxIndex = 0;
|
---|
810 |
|
---|
811 | for (int i = 0; i < doubles.length; i++) {
|
---|
812 | if ((i == 0) || (doubles[i] > maximum)) {
|
---|
813 | maxIndex = i;
|
---|
814 | maximum = doubles[i];
|
---|
815 | }
|
---|
816 | }
|
---|
817 |
|
---|
818 | return maxIndex;
|
---|
819 | }
|
---|
820 |
|
---|
821 | /**
|
---|
822 | * Returns index of maximum element in a given
|
---|
823 | * array of integers. First maximum is returned.
|
---|
824 | *
|
---|
825 | * @param ints the array of integers
|
---|
826 | * @return the index of the maximum element
|
---|
827 | */
|
---|
828 | public static int maxIndex(int [] ints) {
|
---|
829 |
|
---|
830 | int maximum = 0;
|
---|
831 | int maxIndex = 0;
|
---|
832 |
|
---|
833 | for (int i = 0; i < ints.length; i++) {
|
---|
834 | if ((i == 0) || (ints[i] > maximum)) {
|
---|
835 | maxIndex = i;
|
---|
836 | maximum = ints[i];
|
---|
837 | }
|
---|
838 | }
|
---|
839 |
|
---|
840 | return maxIndex;
|
---|
841 | }
|
---|
842 |
|
---|
843 | /**
|
---|
844 | * Computes the mean for an array of doubles.
|
---|
845 | *
|
---|
846 | * @param vector the array
|
---|
847 | * @return the mean
|
---|
848 | */
|
---|
849 | public static double mean(double[] vector) {
|
---|
850 |
|
---|
851 | double sum = 0;
|
---|
852 |
|
---|
853 | if (vector.length == 0) {
|
---|
854 | return 0;
|
---|
855 | }
|
---|
856 | for (int i = 0; i < vector.length; i++) {
|
---|
857 | sum += vector[i];
|
---|
858 | }
|
---|
859 | return sum / (double) vector.length;
|
---|
860 | }
|
---|
861 |
|
---|
862 | /**
|
---|
863 | * Returns index of minimum element in a given
|
---|
864 | * array of integers. First minimum is returned.
|
---|
865 | *
|
---|
866 | * @param ints the array of integers
|
---|
867 | * @return the index of the minimum element
|
---|
868 | */
|
---|
869 | public static int minIndex(int [] ints) {
|
---|
870 |
|
---|
871 | int minimum = 0;
|
---|
872 | int minIndex = 0;
|
---|
873 |
|
---|
874 | for (int i = 0; i < ints.length; i++) {
|
---|
875 | if ((i == 0) || (ints[i] < minimum)) {
|
---|
876 | minIndex = i;
|
---|
877 | minimum = ints[i];
|
---|
878 | }
|
---|
879 | }
|
---|
880 |
|
---|
881 | return minIndex;
|
---|
882 | }
|
---|
883 |
|
---|
884 | /**
|
---|
885 | * Returns index of minimum element in a given
|
---|
886 | * array of doubles. First minimum is returned.
|
---|
887 | *
|
---|
888 | * @param doubles the array of doubles
|
---|
889 | * @return the index of the minimum element
|
---|
890 | */
|
---|
891 | public static int minIndex(double [] doubles) {
|
---|
892 |
|
---|
893 | double minimum = 0;
|
---|
894 | int minIndex = 0;
|
---|
895 |
|
---|
896 | for (int i = 0; i < doubles.length; i++) {
|
---|
897 | if ((i == 0) || (doubles[i] < minimum)) {
|
---|
898 | minIndex = i;
|
---|
899 | minimum = doubles[i];
|
---|
900 | }
|
---|
901 | }
|
---|
902 |
|
---|
903 | return minIndex;
|
---|
904 | }
|
---|
905 |
|
---|
906 | /**
|
---|
907 | * Normalizes the doubles in the array by their sum.
|
---|
908 | *
|
---|
909 | * @param doubles the array of double
|
---|
910 | * @exception IllegalArgumentException if sum is Zero or NaN
|
---|
911 | */
|
---|
912 | public static void normalize(double[] doubles) {
|
---|
913 |
|
---|
914 | double sum = 0;
|
---|
915 | for (int i = 0; i < doubles.length; i++) {
|
---|
916 | sum += doubles[i];
|
---|
917 | }
|
---|
918 | normalize(doubles, sum);
|
---|
919 | }
|
---|
920 |
|
---|
921 | /**
|
---|
922 | * Normalizes the doubles in the array using the given value.
|
---|
923 | *
|
---|
924 | * @param doubles the array of double
|
---|
925 | * @param sum the value by which the doubles are to be normalized
|
---|
926 | * @exception IllegalArgumentException if sum is zero or NaN
|
---|
927 | */
|
---|
928 | public static void normalize(double[] doubles, double sum) {
|
---|
929 |
|
---|
930 | if (Double.isNaN(sum)) {
|
---|
931 | throw new IllegalArgumentException("Can't normalize array. Sum is NaN.");
|
---|
932 | }
|
---|
933 | if (sum == 0) {
|
---|
934 | // Maybe this should just be a return.
|
---|
935 | throw new IllegalArgumentException("Can't normalize array. Sum is zero.");
|
---|
936 | }
|
---|
937 | for (int i = 0; i < doubles.length; i++) {
|
---|
938 | doubles[i] /= sum;
|
---|
939 | }
|
---|
940 | }
|
---|
941 |
|
---|
942 | /**
|
---|
943 | * Rounds a double to the next nearest integer value. The JDK version
|
---|
944 | * of it doesn't work properly.
|
---|
945 | *
|
---|
946 | * @param value the double value
|
---|
947 | * @return the resulting integer value
|
---|
948 | */
|
---|
949 | public static int round(double value) {
|
---|
950 |
|
---|
951 | int roundedValue = value > 0
|
---|
952 | ? (int)(value + 0.5)
|
---|
953 | : -(int)(Math.abs(value) + 0.5);
|
---|
954 |
|
---|
955 | return roundedValue;
|
---|
956 | }
|
---|
957 |
|
---|
958 | /**
|
---|
959 | * Rounds a double to the given number of decimal places.
|
---|
960 | *
|
---|
961 | * @param value the double value
|
---|
962 | * @param afterDecimalPoint the number of digits after the decimal point
|
---|
963 | * @return the double rounded to the given precision
|
---|
964 | */
|
---|
965 | public static double roundDouble(double value,int afterDecimalPoint) {
|
---|
966 |
|
---|
967 | double mask = Math.pow(10.0, (double)afterDecimalPoint);
|
---|
968 |
|
---|
969 | return (double)(Math.round(value * mask)) / mask;
|
---|
970 | }
|
---|
971 |
|
---|
972 | /**
|
---|
973 | * Sorts a given array of integers in ascending order and returns an
|
---|
974 | * array of integers with the positions of the elements of the original
|
---|
975 | * array in the sorted array. The sort is stable. (Equal elements remain
|
---|
976 | * in their original order.)
|
---|
977 | *
|
---|
978 | * @param array this array is not changed by the method!
|
---|
979 | * @return an array of integers with the positions in the sorted
|
---|
980 | * array.
|
---|
981 | */
|
---|
982 | public static int[] sort(int [] array) {
|
---|
983 |
|
---|
984 | int [] index = new int[array.length];
|
---|
985 | int [] newIndex = new int[array.length];
|
---|
986 | int [] helpIndex;
|
---|
987 | int numEqual;
|
---|
988 |
|
---|
989 | for (int i = 0; i < index.length; i++) {
|
---|
990 | index[i] = i;
|
---|
991 | }
|
---|
992 | quickSort(array, index, 0, array.length - 1);
|
---|
993 |
|
---|
994 | // Make sort stable
|
---|
995 | int i = 0;
|
---|
996 | while (i < index.length) {
|
---|
997 | numEqual = 1;
|
---|
998 | for (int j = i + 1; ((j < index.length)
|
---|
999 | && (array[index[i]] == array[index[j]]));
|
---|
1000 | j++) {
|
---|
1001 | numEqual++;
|
---|
1002 | }
|
---|
1003 | if (numEqual > 1) {
|
---|
1004 | helpIndex = new int[numEqual];
|
---|
1005 | for (int j = 0; j < numEqual; j++) {
|
---|
1006 | helpIndex[j] = i + j;
|
---|
1007 | }
|
---|
1008 | quickSort(index, helpIndex, 0, numEqual - 1);
|
---|
1009 | for (int j = 0; j < numEqual; j++) {
|
---|
1010 | newIndex[i + j] = index[helpIndex[j]];
|
---|
1011 | }
|
---|
1012 | i += numEqual;
|
---|
1013 | } else {
|
---|
1014 | newIndex[i] = index[i];
|
---|
1015 | i++;
|
---|
1016 | }
|
---|
1017 | }
|
---|
1018 | return newIndex;
|
---|
1019 | }
|
---|
1020 |
|
---|
1021 | /**
|
---|
1022 | * Sorts a given array of doubles in ascending order and returns an
|
---|
1023 | * array of integers with the positions of the elements of the
|
---|
1024 | * original array in the sorted array. NOTE THESE CHANGES: the sort
|
---|
1025 | * is no longer stable and it doesn't use safe floating-point
|
---|
1026 | * comparisons anymore. Occurrences of Double.NaN are treated as
|
---|
1027 | * Double.MAX_VALUE
|
---|
1028 | *
|
---|
1029 | * @param array this array is not changed by the method!
|
---|
1030 | * @return an array of integers with the positions in the sorted
|
---|
1031 | * array.
|
---|
1032 | */
|
---|
1033 | public static int[] sort(double [] array) {
|
---|
1034 |
|
---|
1035 | int [] index = new int[array.length];
|
---|
1036 | array = (double [])array.clone();
|
---|
1037 | for (int i = 0; i < index.length; i++) {
|
---|
1038 | index[i] = i;
|
---|
1039 | if (Double.isNaN(array[i])) {
|
---|
1040 | array[i] = Double.MAX_VALUE;
|
---|
1041 | }
|
---|
1042 | }
|
---|
1043 | quickSort(array, index, 0, array.length - 1);
|
---|
1044 | return index;
|
---|
1045 | }
|
---|
1046 |
|
---|
1047 | /**
|
---|
1048 | * Sorts a given array of doubles in ascending order and returns an
|
---|
1049 | * array of integers with the positions of the elements of the original
|
---|
1050 | * array in the sorted array. The sort is stable (Equal elements remain
|
---|
1051 | * in their original order.) Occurrences of Double.NaN are treated as
|
---|
1052 | * Double.MAX_VALUE
|
---|
1053 | *
|
---|
1054 | * @param array this array is not changed by the method!
|
---|
1055 | * @return an array of integers with the positions in the sorted
|
---|
1056 | * array.
|
---|
1057 | */
|
---|
1058 | public static int[] stableSort(double [] array){
|
---|
1059 |
|
---|
1060 | int [] index = new int[array.length];
|
---|
1061 | int [] newIndex = new int[array.length];
|
---|
1062 | int [] helpIndex;
|
---|
1063 | int numEqual;
|
---|
1064 |
|
---|
1065 | array = (double [])array.clone();
|
---|
1066 | for (int i = 0; i < index.length; i++) {
|
---|
1067 | index[i] = i;
|
---|
1068 | if (Double.isNaN(array[i])) {
|
---|
1069 | array[i] = Double.MAX_VALUE;
|
---|
1070 | }
|
---|
1071 | }
|
---|
1072 | quickSort(array,index,0,array.length-1);
|
---|
1073 |
|
---|
1074 | // Make sort stable
|
---|
1075 |
|
---|
1076 | int i = 0;
|
---|
1077 | while (i < index.length) {
|
---|
1078 | numEqual = 1;
|
---|
1079 | for (int j = i+1; ((j < index.length) && Utils.eq(array[index[i]],
|
---|
1080 | array[index[j]])); j++)
|
---|
1081 | numEqual++;
|
---|
1082 | if (numEqual > 1) {
|
---|
1083 | helpIndex = new int[numEqual];
|
---|
1084 | for (int j = 0; j < numEqual; j++)
|
---|
1085 | helpIndex[j] = i+j;
|
---|
1086 | quickSort(index, helpIndex, 0, numEqual-1);
|
---|
1087 | for (int j = 0; j < numEqual; j++)
|
---|
1088 | newIndex[i+j] = index[helpIndex[j]];
|
---|
1089 | i += numEqual;
|
---|
1090 | } else {
|
---|
1091 | newIndex[i] = index[i];
|
---|
1092 | i++;
|
---|
1093 | }
|
---|
1094 | }
|
---|
1095 |
|
---|
1096 | return newIndex;
|
---|
1097 | }
|
---|
1098 |
|
---|
1099 | /**
|
---|
1100 | * Computes the variance for an array of doubles.
|
---|
1101 | *
|
---|
1102 | * @param vector the array
|
---|
1103 | * @return the variance
|
---|
1104 | */
|
---|
1105 | public static double variance(double[] vector) {
|
---|
1106 |
|
---|
1107 | double sum = 0, sumSquared = 0;
|
---|
1108 |
|
---|
1109 | if (vector.length <= 1) {
|
---|
1110 | return 0;
|
---|
1111 | }
|
---|
1112 | for (int i = 0; i < vector.length; i++) {
|
---|
1113 | sum += vector[i];
|
---|
1114 | sumSquared += (vector[i] * vector[i]);
|
---|
1115 | }
|
---|
1116 | return (sumSquared - (sum * sum / (double) vector.length)) /
|
---|
1117 | (double) (vector.length - 1);
|
---|
1118 | }
|
---|
1119 |
|
---|
1120 | /**
|
---|
1121 | * Computes the sum of the elements of an array of doubles.
|
---|
1122 | *
|
---|
1123 | * @param doubles the array of double
|
---|
1124 | * @returns the sum of the elements
|
---|
1125 | */
|
---|
1126 | public static double sum(double[] doubles) {
|
---|
1127 |
|
---|
1128 | double sum = 0;
|
---|
1129 |
|
---|
1130 | for (int i = 0; i < doubles.length; i++) {
|
---|
1131 | sum += doubles[i];
|
---|
1132 | }
|
---|
1133 | return sum;
|
---|
1134 | }
|
---|
1135 |
|
---|
1136 | /**
|
---|
1137 | * Computes the sum of the elements of an array of integers.
|
---|
1138 | *
|
---|
1139 | * @param ints the array of integers
|
---|
1140 | * @returns the sum of the elements
|
---|
1141 | */
|
---|
1142 | public static int sum(int[] ints) {
|
---|
1143 |
|
---|
1144 | int sum = 0;
|
---|
1145 |
|
---|
1146 | for (int i = 0; i < ints.length; i++) {
|
---|
1147 | sum += ints[i];
|
---|
1148 | }
|
---|
1149 | return sum;
|
---|
1150 | }
|
---|
1151 |
|
---|
1152 | /**
|
---|
1153 | * Returns c*log2(c) for a given integer value c.
|
---|
1154 | *
|
---|
1155 | * @param c an integer value
|
---|
1156 | * @returns c*log2(c) (but is careful to return 0 if c is 0)
|
---|
1157 | */
|
---|
1158 | public static double xlogx(int c) {
|
---|
1159 |
|
---|
1160 | if (c == 0) {
|
---|
1161 | return 0.0;
|
---|
1162 | }
|
---|
1163 | return c * Utils.log2((double) c);
|
---|
1164 | }
|
---|
1165 |
|
---|
1166 | /**
|
---|
1167 | * Implements quicksort for an array of indices.
|
---|
1168 | *
|
---|
1169 | * @param array the array of integers to be sorted
|
---|
1170 | * @param index the index which should contain the positions in the
|
---|
1171 | * sorted array
|
---|
1172 | * @param lo0 the first index of the subset to be sorted
|
---|
1173 | * @param hi0 the last index of the subset to be sorted
|
---|
1174 | */
|
---|
1175 | private static void quickSort(int [] array, int [] index,
|
---|
1176 | int lo0, int hi0) {
|
---|
1177 |
|
---|
1178 | int lo = lo0;
|
---|
1179 | int hi = hi0;
|
---|
1180 | int mid;
|
---|
1181 | int help;
|
---|
1182 |
|
---|
1183 | if (hi0 > lo0) {
|
---|
1184 |
|
---|
1185 | // Arbitrarily establishing partition element as the midpoint of
|
---|
1186 | // the array.
|
---|
1187 | mid = array[index[(lo0 + hi0) / 2]];
|
---|
1188 |
|
---|
1189 | // loop through the array until indices cross
|
---|
1190 | while (lo <= hi) {
|
---|
1191 |
|
---|
1192 | // find the first element that is greater than or equal to
|
---|
1193 | // the partition element starting from the left Index.
|
---|
1194 | while ((array[index[lo]] < mid) && (lo < hi0)) {
|
---|
1195 | ++lo;
|
---|
1196 | }
|
---|
1197 |
|
---|
1198 | // find an element that is smaller than or equal to
|
---|
1199 | // the partition element starting from the right Index.
|
---|
1200 | while ((array[index[hi]] > mid) && (hi > lo0)) {
|
---|
1201 | --hi;
|
---|
1202 | }
|
---|
1203 |
|
---|
1204 | // if the indexes have not crossed, swap
|
---|
1205 | if (lo <= hi) {
|
---|
1206 | help = index[lo];
|
---|
1207 | index[lo] = index[hi];
|
---|
1208 | index[hi] = help;
|
---|
1209 | ++lo;
|
---|
1210 | --hi;
|
---|
1211 | }
|
---|
1212 | }
|
---|
1213 |
|
---|
1214 | // If the right index has not reached the left side of array
|
---|
1215 | // must now sort the left partition.
|
---|
1216 | if (lo0 < hi) {
|
---|
1217 | quickSort(array, index, lo0, hi);
|
---|
1218 | }
|
---|
1219 |
|
---|
1220 | // If the left index has not reached the right side of array
|
---|
1221 | // must now sort the right partition.
|
---|
1222 | if (lo < hi0) {
|
---|
1223 | quickSort(array, index, lo, hi0);
|
---|
1224 | }
|
---|
1225 | }
|
---|
1226 | }
|
---|
1227 |
|
---|
1228 | /**
|
---|
1229 | * Implements unsafe quicksort for an array of indices.
|
---|
1230 | *
|
---|
1231 | * @param array the array of doubles to be sorted
|
---|
1232 | * @param index the index which should contain the positions in the
|
---|
1233 | * sorted array
|
---|
1234 | * @param lo0 the first index of the subset to be sorted
|
---|
1235 | * @param hi0 the last index of the subset to be sorted
|
---|
1236 | */
|
---|
1237 | private static void quickSort(double [] array, int [] index, int lo0, int hi0) {
|
---|
1238 |
|
---|
1239 | int lo = lo0;
|
---|
1240 | int hi = hi0;
|
---|
1241 | double mid;
|
---|
1242 | int help;
|
---|
1243 |
|
---|
1244 | if (hi0 > lo0) {
|
---|
1245 |
|
---|
1246 | // Arbitrarily establishing partition element as the midpoint of
|
---|
1247 | // the array.
|
---|
1248 | mid = array[index[(lo0 + hi0) / 2]];
|
---|
1249 |
|
---|
1250 | // loop through the array until indices cross
|
---|
1251 | while (lo <= hi) {
|
---|
1252 |
|
---|
1253 | // find the first element that is greater than or equal to
|
---|
1254 | // the partition element starting from the left Index.
|
---|
1255 | while ((array[index[lo]] < mid) && (lo < hi0)) {
|
---|
1256 | ++lo;
|
---|
1257 | }
|
---|
1258 |
|
---|
1259 | // find an element that is smaller than or equal to
|
---|
1260 | // the partition element starting from the right Index.
|
---|
1261 | while ((array[index[hi]] > mid) && (hi > lo0)) {
|
---|
1262 | --hi;
|
---|
1263 | }
|
---|
1264 |
|
---|
1265 | // if the indexes have not crossed, swap
|
---|
1266 | if (lo <= hi) {
|
---|
1267 | help = index[lo];
|
---|
1268 | index[lo] = index[hi];
|
---|
1269 | index[hi] = help;
|
---|
1270 | ++lo;
|
---|
1271 | --hi;
|
---|
1272 | }
|
---|
1273 | }
|
---|
1274 |
|
---|
1275 | // If the right index has not reached the left side of array
|
---|
1276 | // must now sort the left partition.
|
---|
1277 | if (lo0 < hi) {
|
---|
1278 | quickSort(array, index, lo0, hi);
|
---|
1279 | }
|
---|
1280 |
|
---|
1281 | // If the left index has not reached the right side of array
|
---|
1282 | // must now sort the right partition.
|
---|
1283 | if (lo < hi0) {
|
---|
1284 | quickSort(array, index, lo, hi0);
|
---|
1285 | }
|
---|
1286 | }
|
---|
1287 | }
|
---|
1288 |
|
---|
1289 | /**
|
---|
1290 | * Main method for testing this class.
|
---|
1291 | *
|
---|
1292 | * @param ops some dummy options
|
---|
1293 | */
|
---|
1294 | public static void main(String[] ops) {
|
---|
1295 |
|
---|
1296 | double[] doubles = {4.5, 6.7, Double.NaN, 3.4, 4.8, 1.2, 3.4};
|
---|
1297 | int[] ints = {12, 6, 2, 18, 16, 6, 7, 5};
|
---|
1298 |
|
---|
1299 | try {
|
---|
1300 |
|
---|
1301 | // Option handling
|
---|
1302 | System.out.println("First option split up:");
|
---|
1303 | if (ops.length > 0) {
|
---|
1304 | String[] firstOptionSplitUp = Utils.splitOptions(ops[0]);
|
---|
1305 | for (int i = 0; i < firstOptionSplitUp.length; i ++) {
|
---|
1306 | System.out.println(firstOptionSplitUp[i]);
|
---|
1307 | }
|
---|
1308 | }
|
---|
1309 | System.out.println("Partitioned options: ");
|
---|
1310 | String[] partitionedOptions = Utils.partitionOptions(ops);
|
---|
1311 | for (int i = 0; i < partitionedOptions.length; i++) {
|
---|
1312 | System.out.println(partitionedOptions[i]);
|
---|
1313 | }
|
---|
1314 | System.out.println("Get flag -f: " + Utils.getFlag('f', ops));
|
---|
1315 | System.out.println("Get option -o: " + Utils.getOption('o', ops));
|
---|
1316 | System.out.println("Checking for remaining options... ");
|
---|
1317 | Utils.checkForRemainingOptions(ops);
|
---|
1318 |
|
---|
1319 | // Statistics
|
---|
1320 | System.out.println("Original array (doubles): ");
|
---|
1321 | for (int i = 0; i < doubles.length; i++) {
|
---|
1322 | System.out.print(doubles[i] + " ");
|
---|
1323 | }
|
---|
1324 | System.out.println();
|
---|
1325 | System.out.println("Original array (ints): ");
|
---|
1326 | for (int i = 0; i < ints.length; i++) {
|
---|
1327 | System.out.print(ints[i] + " ");
|
---|
1328 | }
|
---|
1329 | System.out.println();
|
---|
1330 | System.out.println("Correlation: " + Utils.correlation(doubles, doubles,
|
---|
1331 | doubles.length));
|
---|
1332 | System.out.println("Mean: " + Utils.mean(doubles));
|
---|
1333 | System.out.println("Variance: " + Utils.variance(doubles));
|
---|
1334 | System.out.println("Sum (doubles): " + Utils.sum(doubles));
|
---|
1335 | System.out.println("Sum (ints): " + Utils.sum(ints));
|
---|
1336 | System.out.println("Max index (doubles): " + Utils.maxIndex(doubles));
|
---|
1337 | System.out.println("Max index (ints): " + Utils.maxIndex(ints));
|
---|
1338 | System.out.println("Min index (doubles): " + Utils.minIndex(doubles));
|
---|
1339 | System.out.println("Min index (ints): " + Utils.minIndex(ints));
|
---|
1340 |
|
---|
1341 | // Sorting and normalizing
|
---|
1342 | System.out.println("Sorted array (doubles): ");
|
---|
1343 | int[] sorted = Utils.sort(doubles);
|
---|
1344 | for (int i = 0; i < doubles.length; i++) {
|
---|
1345 | System.out.print(doubles[sorted[i]] + " ");
|
---|
1346 | }
|
---|
1347 | System.out.println();
|
---|
1348 | System.out.println("Normalized array (doubles): ");
|
---|
1349 | Utils.normalize(doubles);
|
---|
1350 | for (int i = 0; i < doubles.length; i++) {
|
---|
1351 | System.out.print(doubles[i] + " ");
|
---|
1352 | }
|
---|
1353 | System.out.println();
|
---|
1354 | System.out.println("Normalized again (doubles): ");
|
---|
1355 | Utils.normalize(doubles, Utils.sum(doubles));
|
---|
1356 | for (int i = 0; i < doubles.length; i++) {
|
---|
1357 | System.out.print(doubles[i] + " ");
|
---|
1358 | }
|
---|
1359 | System.out.println();
|
---|
1360 |
|
---|
1361 | // Pretty-printing
|
---|
1362 | System.out.println("-4.58: " + Utils.doubleToString(-4.57826535, 2));
|
---|
1363 | System.out.println("-6.78: " + Utils.doubleToString(-6.78214234, 6,2));
|
---|
1364 |
|
---|
1365 | // Comparisons
|
---|
1366 | System.out.println("5.70001 == 5.7 ? " + Utils.eq(5.70001, 5.7));
|
---|
1367 | System.out.println("5.70001 > 5.7 ? " + Utils.gr(5.70001, 5.7));
|
---|
1368 | System.out.println("5.70001 >= 5.7 ? " + Utils.grOrEq(5.70001, 5.7));
|
---|
1369 | System.out.println("5.7 < 5.70001 ? " + Utils.sm(5.7, 5.70001));
|
---|
1370 | System.out.println("5.7 <= 5.70001 ? " + Utils.smOrEq(5.7, 5.70001));
|
---|
1371 |
|
---|
1372 | // Math
|
---|
1373 | System.out.println("Info (ints): " + Utils.info(ints));
|
---|
1374 | System.out.println("log2(4.6): " + Utils.log2(4.6));
|
---|
1375 | System.out.println("5 * log(5): " + Utils.xlogx(5));
|
---|
1376 | System.out.println("5.5 rounded: " + Utils.round(5.5));
|
---|
1377 | System.out.println("5.55555 rounded to 2 decimal places: " +
|
---|
1378 | Utils.roundDouble(5.55555, 2));
|
---|
1379 | } catch (Exception e) {
|
---|
1380 | e.printStackTrace();
|
---|
1381 | }
|
---|
1382 | }
|
---|
1383 | }
|
---|
1384 |
|
---|