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 Matlab { 036 037 public static String[] SEARCH = new String[] {}; 038 039 static { 040 try { 041 SEARCH = new String[] { System.getProperty("Matlab"), 042 System.getProperty("user.home") + "/matlab/bin/matlab", "/usr/bin/matlab", 043 "/opt/matlab/bin/matlab" }; 044 } catch (Exception e) { 045 } 046 } 047 048 public static final String MATLABPARAMETERS = "-nosplash -nojvm"; 049 050 private static String pathToMatlab = null; 051 052 private BufferedReader input = null; 053 054 private BufferedWriter output = null; 055 056 private BufferedReader error = null; 057 058 private Process matlabProcess = null; 059 060 private boolean running = false; 061 062 private static Matlab matlab = null; 063 064 public static synchronized Matlab getInstance() throws Exception { 065 if (matlab == null) { 066 matlab = getInstance(findMatlab()); 067 } 068 return matlab; 069 } 070 071 private static String findMatlab() { 072 if (pathToMatlab == null) { 073 File file = null; 074 for (String s : SEARCH) { 075 if (s != null) { 076 file = new File(s); 077 if (file.exists()) { 078 pathToMatlab = file.getAbsolutePath(); 079 return pathToMatlab; 080 } 081 } 082 } 083 } 084 return pathToMatlab; 085 } 086 087 public static synchronized Matlab getInstance(String pathToMatlab) throws Exception { 088 if (matlab == null) { 089 matlab = new Matlab(pathToMatlab); 090 } 091 return matlab; 092 } 093 094 private Matlab(String pathToMatlab) throws Exception { 095 matlabProcess = Runtime.getRuntime().exec(pathToMatlab + " " + MATLABPARAMETERS); 096 output = new BufferedWriter(new OutputStreamWriter(matlabProcess.getOutputStream())); 097 input = new BufferedReader(new InputStreamReader(matlabProcess.getInputStream())); 098 error = new BufferedReader(new InputStreamReader(matlabProcess.getErrorStream())); 099 String startMessage = getFromMatlab(); 100 if (startMessage != null && startMessage.length() > 0) { 101 running = true; 102 return; 103 } 104 throw new Exception("could not start Matlab"); 105 } 106 107 private synchronized String getFromMatlab() throws Exception { 108 boolean endSeen = false; 109 StringBuilder sb = new StringBuilder(); 110 111 while (true) { 112 while (!input.ready()) { 113 Thread.yield(); 114 } 115 while (input.ready()) { 116 117 char c = (char) input.read(); 118 sb.append(c); 119 120 if (c == '>') { 121 if (endSeen) { 122 return sb.substring(0, sb.length() - 2); 123 } 124 endSeen = true; 125 } else { 126 endSeen = false; 127 } 128 } 129 } 130 } 131 132 public String execute(String command) throws Exception { 133 sendToMatlab(command); 134 return getFromMatlab(); 135 } 136 137 public synchronized void shutdown() throws Exception { 138 sendToMatlab("exit"); 139 matlabProcess.waitFor(); 140 output.close(); 141 input.close(); 142 } 143 144 private synchronized void sendToMatlab(String command) throws Exception { 145 if (!command.endsWith("\n")) { 146 command = command + "\n"; 147 } 148 output.write(command, 0, command.length()); 149 output.flush(); 150 } 151 152 public void setMatrix(String label, Matrix matrix) throws Exception { 153 execute(label + "=" + matrix.exportToString(FileFormat.M)); 154 } 155 156 public Matrix getMatrix(String label) throws Exception { 157 try { 158 String rawRows = execute("fprintf(1,'%d\\n',size(" + label + ",1));"); 159 int rows = Integer.parseInt(rawRows.trim()); 160 String rawCols = execute("fprintf(1,'%d\\n',size(" + label + ",2));"); 161 int cols = Integer.parseInt(rawCols.trim()); 162 163 String rawText = execute("fprintf(1,'%55.55f\\n'," + label + ")"); 164 String[] rawValues = rawText.split("\n"); 165 166 Matrix matrix = Matrix.factory.zeros(rows, cols); 167 168 int i = 0; 169 for (int c = 0; c < cols; c++) { 170 for (int r = 0; r < rows; r++) { 171 matrix.setAsDouble(Double.parseDouble(rawValues[i++]), r, c); 172 } 173 } 174 175 return matrix; 176 } catch (Exception e) { 177 e.printStackTrace(); 178 return null; 179 } 180 } 181 182 public static boolean isAvailable() { 183 return findMatlab() != null; 184 } 185 186 public void plot(Matrix matrix, String... format) throws Exception { 187 setMatrix("ujmpmatrix", matrix); 188 execute("figure;"); 189 execute("plot(ujmpmatrix" + toString(format) + ");"); 190 } 191 192 public void hist(Matrix matrix, String... format) throws Exception { 193 setMatrix("ujmpmatrix", matrix); 194 execute("figure;"); 195 execute("hist(ujmpmatrix" + toString(format) + ");"); 196 } 197 198 public void surf(Matrix matrix, String... format) throws Exception { 199 setMatrix("ujmpmatrix", matrix); 200 execute("figure;"); 201 execute("surf(ujmpmatrix" + toString(format) + ");"); 202 } 203 204 public void imagesc(Matrix matrix, String... format) throws Exception { 205 setMatrix("ujmpmatrix", matrix); 206 execute("figure;"); 207 execute("imagesc(ujmpmatrix" + toString(format) + ");"); 208 } 209 210 public void bar(Matrix matrix, String... format) throws Exception { 211 setMatrix("ujmpmatrix", matrix); 212 execute("figure;"); 213 execute("bar(ujmpmatrix" + toString(format) + ");"); 214 } 215 216 public void errorbar(Matrix x, Matrix y, Matrix e, String... format) throws Exception { 217 setMatrix("ujmpmatrix_x", x); 218 setMatrix("ujmpmatrix_y", y); 219 setMatrix("ujmpmatrix_e", e); 220 execute("figure;"); 221 execute("errorbar(ujmpmatrix_x,ujmpmatrix_y,ujmpmatrix_e" + toString(format) + ");"); 222 } 223 224 public void barh(Matrix matrix, String... format) throws Exception { 225 setMatrix("ujmpmatrix", matrix); 226 execute("figure;"); 227 execute("barh(ujmpmatrix" + toString(format) + ");"); 228 } 229 230 public void stem(Matrix matrix, String... format) throws Exception { 231 setMatrix("ujmpmatrix", matrix); 232 execute("figure;"); 233 execute("stem(ujmpmatrix" + toString(format) + ");"); 234 } 235 236 public void pie(Matrix matrix, String... format) throws Exception { 237 setMatrix("ujmpmatrix", matrix); 238 execute("figure;"); 239 execute("pie(ujmpmatrix" + toString(format) + ");"); 240 } 241 242 public void pie3(Matrix matrix, String... format) throws Exception { 243 setMatrix("ujmpmatrix", matrix); 244 execute("figure;"); 245 execute("pie3(ujmpmatrix" + toString(format) + ");"); 246 } 247 248 public void plotmatrix(Matrix matrix, String... format) throws Exception { 249 setMatrix("ujmpmatrix", matrix); 250 execute("figure;"); 251 execute("plotmatrix(ujmpmatrix" + toString(format) + ");"); 252 } 253 254 public void plot(Matrix x, Matrix y, String... format) throws Exception { 255 setMatrix("ujmpmatrix_x", x); 256 setMatrix("ujmpmatrix_y", y); 257 execute("figure;"); 258 execute("plot(ujmpmatrix_x,ujmpmatrix_y" + toString(format) + ");"); 259 } 260 261 public static String toString(String[] strings) { 262 if (strings.length != 0) { 263 return ",'" + strings[0] + "'"; 264 } else { 265 return ""; 266 } 267 } 268 }