001 /* 002 * Copyright (C) 2008-2010 by Holger Arndt 003 * 004 * This file is part of the Universal Java Matrix Package (UJMP). 005 * See the NOTICE file distributed with this work for additional 006 * information regarding copyright ownership and licensing. 007 * 008 * UJMP is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU Lesser General Public License as 010 * published by the Free Software Foundation; either version 2 011 * of the License, or (at your option) any later version. 012 * 013 * UJMP is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU Lesser General Public License for more details. 017 * 018 * You should have received a copy of the GNU Lesser General Public 019 * License along with UJMP; if not, write to the 020 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 021 * Boston, MA 02110-1301 USA 022 */ 023 024 package org.ujmp.core.util; 025 026 import java.io.BufferedReader; 027 import java.io.BufferedWriter; 028 import java.io.File; 029 import java.io.InputStreamReader; 030 import java.io.OutputStreamWriter; 031 032 import org.ujmp.core.Matrix; 033 import org.ujmp.core.enums.FileFormat; 034 035 public class Octave { 036 037 public static String[] SEARCH = new String[] {}; 038 039 static { 040 try { 041 SEARCH = new String[] { System.getProperty("Octave"), "/usr/bin/octave", 042 "/opt/octave/bin/octave" }; 043 } catch (Exception e) { 044 } 045 } 046 047 public static final int POLLINTERVAL = 50; 048 049 public static final int MAXPOLLS = 10; 050 051 private BufferedReader input = null; 052 053 private BufferedWriter output = null; 054 055 private BufferedReader error = null; 056 057 private Process octaveProcess = null; 058 059 private boolean running = false; 060 061 private static Octave octave = null; 062 063 private static String pathToOctave = null; 064 065 public static synchronized Octave getInstance() throws Exception { 066 if (octave == null) { 067 octave = getInstance(findOctave()); 068 } 069 return octave; 070 } 071 072 public static synchronized Octave getInstance(String pathToOctave) throws Exception { 073 if (octave == null) { 074 octave = new Octave(pathToOctave); 075 } 076 return octave; 077 } 078 079 private Octave(String pathToOctave) throws Exception { 080 octaveProcess = Runtime.getRuntime().exec(pathToOctave); 081 output = new BufferedWriter(new OutputStreamWriter(octaveProcess.getOutputStream())); 082 input = new BufferedReader(new InputStreamReader(octaveProcess.getInputStream())); 083 error = new BufferedReader(new InputStreamReader(octaveProcess.getErrorStream())); 084 String startMessage = getFromOctave(); 085 if (startMessage != null && startMessage.length() > 0) { 086 running = true; 087 return; 088 } 089 throw new Exception("could not start Octave"); 090 } 091 092 private synchronized String getFromOctave() throws Exception { 093 boolean colonSeen = false; 094 boolean numberSeen = false; 095 StringBuilder sb = new StringBuilder(); 096 097 for (int i = 0; i < MAXPOLLS; i++) { 098 if (!input.ready()) { 099 Thread.sleep(POLLINTERVAL); 100 } else { 101 break; 102 } 103 } 104 105 while (input.ready()) { 106 107 char c = (char) input.read(); 108 sb.append(c); 109 110 if (numberSeen) { 111 if (c == '>') { 112 return sb.toString(); 113 } else { 114 colonSeen = false; 115 numberSeen = false; 116 } 117 } else if (colonSeen) { 118 if (c == '0' || c == '1' || c == '2' || c == '3' || c == '4' || c == '5' 119 || c == '6' || c == '7' || c == '8' || c == '9') { 120 numberSeen = true; 121 } else { 122 colonSeen = false; 123 numberSeen = false; 124 } 125 } else { 126 if (c == ':') { 127 colonSeen = true; 128 } 129 } 130 } 131 return sb.toString(); 132 } 133 134 public String execute(String command) throws Exception { 135 sendToOctave(command); 136 return getFromOctave(); 137 } 138 139 public synchronized void shutdown() throws Exception { 140 sendToOctave("exit"); 141 octaveProcess.waitFor(); 142 output.close(); 143 input.close(); 144 } 145 146 private synchronized void sendToOctave(String command) throws Exception { 147 if (!command.endsWith("\n")) { 148 command = command + "\n"; 149 } 150 output.write(command, 0, command.length()); 151 output.flush(); 152 } 153 154 public void setMatrix(String label, Matrix matrix) throws Exception { 155 execute(label + "=" + matrix.exportToString(FileFormat.M)); 156 } 157 158 private static String findOctave() { 159 if (pathToOctave == null) { 160 File file = null; 161 for (String s : SEARCH) { 162 if (s != null) { 163 file = new File(s); 164 if (file.exists()) { 165 pathToOctave = file.getAbsolutePath(); 166 return pathToOctave; 167 } 168 } 169 } 170 } 171 return pathToOctave; 172 } 173 174 public Matrix getMatrix(String label) throws Exception { 175 try { 176 String rawRows = execute("fprintf(1,'%d\\n',size(" + label + ",1));"); 177 int rows = Integer.parseInt(rawRows.trim()); 178 String rawCols = execute("fprintf(1,'%d\\n',size(" + label + ",2));"); 179 int cols = Integer.parseInt(rawCols.trim()); 180 181 String rawText = execute("fprintf(1,'%55.55f\\n'," + label + ")"); 182 String[] rawValues = rawText.split("\n"); 183 184 Matrix matrix = Matrix.factory.zeros(rows, cols); 185 186 int i = 0; 187 for (int c = 0; c < cols; c++) { 188 for (int r = 0; r < rows; r++) { 189 matrix.setAsDouble(Double.parseDouble(rawValues[i++]), r, c); 190 } 191 } 192 193 return matrix; 194 } catch (Exception e) { 195 e.printStackTrace(); 196 return null; 197 } 198 } 199 200 public static boolean isAvailable() { 201 return findOctave() != null; 202 } 203 204 public void plot(Matrix matrix, String... format) throws Exception { 205 setMatrix("ujmpmatrix", matrix); 206 execute("figure;"); 207 execute("plot(ujmpmatrix" + toString(format) + ");"); 208 } 209 210 public void loglog(Matrix matrix, String... format) throws Exception { 211 setMatrix("ujmpmatrix", matrix); 212 execute("figure;"); 213 execute("loglog(ujmpmatrix" + toString(format) + ");"); 214 } 215 216 public void semilogx(Matrix matrix, String... format) throws Exception { 217 setMatrix("ujmpmatrix", matrix); 218 execute("figure;"); 219 execute("semilogx(ujmpmatrix" + toString(format) + ");"); 220 } 221 222 public void semilogy(Matrix matrix, String... format) throws Exception { 223 setMatrix("ujmpmatrix", matrix); 224 execute("figure;"); 225 execute("semilogy(ujmpmatrix" + toString(format) + ");"); 226 } 227 228 public void bar(Matrix matrix, String... format) throws Exception { 229 setMatrix("ujmpmatrix", matrix); 230 execute("figure;"); 231 execute("bar(ujmpmatrix" + toString(format) + ");"); 232 } 233 234 public void stairs(Matrix matrix, String... format) throws Exception { 235 setMatrix("ujmpmatrix", matrix); 236 execute("figure;"); 237 execute("stairs(ujmpmatrix" + toString(format) + ");"); 238 } 239 240 public void hist(Matrix matrix, String... format) throws Exception { 241 setMatrix("ujmpmatrix", matrix); 242 execute("figure;"); 243 execute("hist(ujmpmatrix" + toString(format) + ");"); 244 } 245 246 public void plot(Matrix x, Matrix y, String... format) throws Exception { 247 setMatrix("ujmpmatrix_x", x); 248 setMatrix("ujmpmatrix_y", y); 249 execute("figure;"); 250 execute("plot(ujmpmatrix_x,ujmpmatrix_y" + toString(format) + ");"); 251 } 252 253 public void loglog(Matrix x, Matrix y, String... format) throws Exception { 254 setMatrix("ujmpmatrix_x", x); 255 setMatrix("ujmpmatrix_y", y); 256 execute("figure;"); 257 execute("loglog(ujmpmatrix_x,ujmpmatrix_y" + toString(format) + ");"); 258 } 259 260 public void semilogx(Matrix x, Matrix y, String... format) throws Exception { 261 setMatrix("ujmpmatrix_x", x); 262 setMatrix("ujmpmatrix_y", y); 263 execute("figure;"); 264 execute("semilogx(ujmpmatrix_x,ujmpmatrix_y" + toString(format) + ");"); 265 } 266 267 public void semilogy(Matrix x, Matrix y, String... format) throws Exception { 268 setMatrix("ujmpmatrix_x", x); 269 setMatrix("ujmpmatrix_y", y); 270 execute("figure;"); 271 execute("semilogy(ujmpmatrix_x,ujmpmatrix_y" + toString(format) + ");"); 272 } 273 274 public void bar(Matrix x, Matrix y, String... format) throws Exception { 275 setMatrix("ujmpmatrix_x", x); 276 setMatrix("ujmpmatrix_y", y); 277 execute("figure;"); 278 execute("bar(ujmpmatrix_x,ujmpmatrix_y" + toString(format) + ");"); 279 } 280 281 public void stairs(Matrix x, Matrix y, String... format) throws Exception { 282 setMatrix("ujmpmatrix_x", x); 283 setMatrix("ujmpmatrix_y", y); 284 execute("figure;"); 285 execute("stairs(ujmpmatrix_x,ujmpmatrix_y" + toString(format) + ");"); 286 } 287 288 public void hist(Matrix x, Matrix y, String... format) throws Exception { 289 setMatrix("ujmpmatrix_x", x); 290 setMatrix("ujmpmatrix_y", y); 291 execute("figure;"); 292 execute("hist(ujmpmatrix_x,ujmpmatrix_y" + toString(format) + ");"); 293 } 294 295 public void polar(Matrix theta, Matrix rho, String... format) throws Exception { 296 setMatrix("ujmpmatrix_theta", theta); 297 setMatrix("ujmpmatrix_rho", rho); 298 execute("figure;"); 299 execute("hist(ujmpmatrix_theta,ujmpmatrix_rho" + toString(format) + ");"); 300 } 301 302 public void contour(Matrix z, Matrix n, Matrix x, Matrix y, String... format) throws Exception { 303 setMatrix("ujmpmatrix_z", z); 304 setMatrix("ujmpmatrix_n", n); 305 setMatrix("ujmpmatrix_x", x); 306 setMatrix("ujmpmatrix_y", y); 307 execute("figure;"); 308 execute("contour(ujmpmatrix_z,ujmpmatrix_n,ujmpmatrix_x,ujmpmatrix_y" + toString(format) 309 + ");"); 310 } 311 312 public void mesh(Matrix x, Matrix y, Matrix z, String... format) throws Exception { 313 setMatrix("ujmpmatrix_x", x); 314 setMatrix("ujmpmatrix_y", y); 315 setMatrix("ujmpmatrix_z", z); 316 execute("figure;"); 317 execute("mesh(ujmpmatrix_x,ujmpmatrix_y,ujmpmatrix_z" + toString(format) + ");"); 318 } 319 320 public static String toString(String[] strings) { 321 if (strings.length != 0) { 322 return ",'" + strings[0] + "'"; 323 } else { 324 return ""; 325 } 326 } 327 328 }