简体   繁体   English

使用 Java 中的 Octave

[英]Using Octave from Java

I need to do some numerical calculations in my java application.我需要在我的 java 应用程序中进行一些数值计算。 For several reasons I decided to use Octave for that purpose.出于多种原因,我决定为此使用 Octave。

I tried to write a simple interface myself.我试着自己写一个简单的界面。 Since Octave can be used via command line I wanted to do this simply by starting a Process via ProcessBuilder and write/read to it using streams.由于 Octave 可以通过命令行使用,因此我想通过 ProcessBuilder 启动一个进程并使用流对其进行写入/读取。

Starting a windwos terminal and interacting with it works fine (with commands like cd, dir, etc).启动windwos 终端并与之交互工作正常(使用cd、dir 等命令)。 When I started octave that way, everything seemed to work fine, but after some tests i found two problems:当我以这种方式开始八度时,一切似乎都很好,但经过一些测试后,我发现了两个问题:

  1. When I produce an error, in my java application the streams close and i can't interact any further instead of just getting the message and move on like in octave itself.当我产生错误时,在我的 Java 应用程序中,流关闭,我无法进一步交互,而不仅仅是获取消息并像八度本身一样继续前进。

  2. I can write to those streams almost as if I was using octave via command line directly, but when i want to create a function, i allways get "warning: function name 'someFunction' does not agree with function filename '' ", although I'm not using a function script file.我几乎可以像直接通过命令行使用八度音程一样写入这些流,但是当我想创建一个函数时,我总是收到“警告:函数名称‘someFunction’与函数文件名‘’不一致”,尽管我' 没有使用函数脚本文件。 In Octave it works.在八度中它有效。

Here is my test-code:这是我的测试代码:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintStream;

public class CLPI {

public static void main(String[] args) {


    String func = "function a = func(b)" + System.lineSeparator()
    + "a = b;" + System.lineSeparator()
    + "endfunction" + System.lineSeparator();

        ProcessBuilder builder = new ProcessBuilder(pathToOctaveCliExe,"--silent","--no-window-system");


        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        try {
            Process p = builder.start();
            String s;

            setUpProcessStreamThreads(p, System.out, System.err);
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(p.getOutputStream ()));

            writer.write(func);
            writer.newLine();
            writer.flush();

            while((s = br.readLine()).compareToIgnoreCase("exit")!=0)
            {
                    writer.write(s);
                    writer.newLine();
                    writer.flush();
            }


            writer.write("quit");
            writer.newLine();
            writer.flush();

            p.destroy();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    System.out.println("Closing program!");
}


public static void setUpProcessStreamThreads(final Process p, final PrintStream ops,PrintStream eps)
{
    final InputStreamReader osr = new InputStreamReader(p.getInputStream());
    final InputStreamReader esr = new InputStreamReader(p.getErrorStream());

    Thread outputThread = new Thread(new Runnable() {
        public void run() {
            BufferedReader br = new BufferedReader(osr);
            String line = null;
            try {
                while ((line = br.readLine()) != null) {
                    ops.println("pos: " + line);
                }
                System.out.println("End of OutputStream!");
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    });
    Thread errorThread = new Thread(new Runnable() {
        public void run() {
            BufferedReader br = new BufferedReader(esr);
            String line = null;
            try {
                while ((line = br.readLine()) != null) {
                    eps.println("pes: " + line);
                }
                System.out.println("End of ErrorStream!");
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    });

    outputThread.setDaemon(true);
    errorThread.setDaemon(true);

    outputThread.start();
    errorThread.start();
    }
}

Does someone know what causes these problems and how to fix them?有人知道导致这些问题的原因以及如何解决吗?

Best regards此致

Thorsen托尔森

ps: Before trying to write my own I looked for an existing interface and found one that should be suitable, called javaoctave ( https://kenai.com/projects/javaoctave/pages/Home ). ps:在尝试编写自己的界面之前,我寻找了一个现有的界面,并找到了一个应该合适的界面,称为 javaoctave ( https://kenai.com/projects/javaoctave/pages/Home )。 On a virtual Ubuntu it worked, but on my system (Windows 10) it blocks when I try to use OctaveEngine's put method (to send a variable from java to octave), without any error message or warning.在虚拟 Ubuntu 上它可以工作,但在我的系统(Windows 10)上,当我尝试使用 OctaveEngine 的 put 方法(将变量从 java 发送到 Octave)时它会阻塞,没有任何错误消息或警告。 In debug mode I get "error: load: failed to load matrix constant", which is probably caused by using the debug mode, so it doesn't give any further (relevant) information.在调试模式下,我收到“错误:加载:无法加载矩阵常量”,这可能是由于使用调试模式引起的,因此它没有提供任何进一步的(相关)信息。

Alternatively to my own interface, if someone knows how to make this old one work again that would be fine for me, too.或者我自己的界面,如果有人知道如何让这个旧界面再次工作,那对我来说也很好。

I totally forgot about this as I was busy.因为忙,我完全忘记了这件事。 I solved it myself and got a working beta version for an interface.我自己解决了这个问题,并获得了一个界面的可用测试版。 You can find it here .你可以在这里找到它。 You will see that it's incomplete and not very well documented, but it's pretty easy to use and give all basic functionality (reading and writing variables, calling functions).您将看到它不完整且没有很好的文档记录,但它非常易于使用并提供所有基本功能(读取和写入变量、调用函数)。

If you use this keep in mind that data exchange between octave and java uses the standard text streams and therefor might be slow for big matrices and many read/write operations.如果您使用它,请记住,octave 和 java 之间的数据交换使用标准文本流,因此对于大矩阵和许多读/写操作可能会很慢。 This is also due to the data being read/written (by default) in its ieee hex representation(-> binary exchange using string characters), but it prevents rounding errors.这也是因为数据在其 ieee 十六进制表示中被读取/写入(默认情况下)(-> 使用字符串字符的二进制交换),但它可以防止舍入错误。 Just keep your data in octave as much as possible.只需将您的数据尽可能保持在八度音程。

I hope this will be helpfull.我希望这会有所帮助。 Feel free to use this, just make your improvements etc accessable for others as well.随意使用它,只需让其他人也可以访问您的改进等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM