最近负责某大学的一个实验数据分析系统,涉及到正太分布、物理公式计算。公式展示网上有许多uedior+ 公式插件。公式计算,最开始采用前端输入公式,进行识别计算,引入了guggy.js。但是这个js可参考的代码太少了,官方文档也很简单,用vue导入后实现不了对div的初始化赋值。后面发现了matlab提供jar包,可以引用之后,调外部的matlab引擎计算。
注意事项:1、需要安装的matlab试用版,并根据官方文档,引入了最新的jar,因非maven管理的jar需要按照以下《springboot添加外部jar包及打包》地址配置。2、使用StringWriter流去获取处理值、错误值。
官网链接:https://ww2.mathworks.cn/help/matlab/matlab-engine-api-for-java.html (也是看了好久的文档,才发现这个JavaAPI文档)
public static void main(String[] args) {
try {
Future<MatlabEngine> engFuture = MatlabEngine.startMatlabAsync();
MatlabEngine engine = engFuture.get();
File file = new File("D:"+File.separator+"Test.txt");
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
file.createNewFile();
}
Writer writer = new FileWriter(file);
Future<Void> future = engine.evalAsync(
"qs=758*145.0377\n" +
"temp=356\n" +
"Ktemp=0.9\n" +
"Fk=75\n" +
"KFk=1-((1-Ktemp)*(Fk-75)/(temp-75))\n" +
"D=89.18/25.4\n" +
"t=7.26/25.4\n" +
"Ap=3.14159*(D-t)*t\n" +
"Ai=3.14159*(D/2-t)^2\n" +
"tm=6.973/25.4\n" +
"Ki=(D^2+(D-2*tm)^2)/(D^2-(D-2*tm)^2)\n" +
"Ti=0.80 \n" +
"Ni=0.90 \n" +
"qa=Ti*qs*KFk\n" +
"qv=Ni*qs*KFk\n" +
"Pin1=1/2/(1+Ki+Ki^2)*(-qa+qa*Ki+(-3*qa^2-6*qa^2*Ki-3*qa^2*Ki^2+4*qv^2+4*Ki*qv^2+4*Ki^2*qv^2)^(1/2))\n" +
"Pin=Pin1\n" +
"Pinm=Pin/145.0377\n" +
"Faz=qa*Ap/1000\n" +
"Fazk=Faz*4.4497\n" +
"Fae=Ai*Pin/1000\n" +
"Faek=Fae*4.4497\n" +
"Faj=Faz-Fae\n" +
"Fajk=Faj*4.4497", writer, writer);
Scanner scan = new Scanner(new FileInputStream(file));
while (scan.hasNextLine()) {
System.out.println(scan.nextLine());
}
} catch (ExecutionException | InterruptedException |IOException e) {
e.printStackTrace();
}
}
因为异步不能得到及时返回值,需要调本地的matlab其实很慢,最后实现同步调用。
@Override
public Result calculate(String id) {
final Formula formula = repository.findById(id).orElse(null);
if (formula != null) {
if (StringUtils.isNotBlank(formula.getContent())) {
try {
MatlabEngine engine = MatlabEngine.startMatlab();
StringWriter writer = new StringWriter();
engine.eval(formula.getContent(), writer, writer);
System.out.println("1String" + writer.toString());
String sb = writer.toString();
writer.close();
return Result.ok().putData(sb);
} catch (InterruptedException | ExecutionException | IOException e) {
e.printStackTrace();
return Result.error("计算失败请确认content公式参数内容正确");
}
}
}
return Result.error("计算失败请确认content公式参数内容正确");
}