Scala调用Matlab(MCR)进行数据拟合并获取结果

背景

硬件设备产生大量传感数据, 需要根据这些原始数据拟合出人能看懂并应用于生活的数据; 公司一直使用Matlab进行数据分析, 本文将介绍如何搭建环境, 并在Akka中调用相关库进行分析.

安装 Matlab

Matlab 编写的文件后缀为m(如: filterF.m), 但可以使用Matlab将其打包生成jar包, 提供给Java生态进行调用.

导出过程很简单, 命令行键入 deploytool → Library Compiler → Java Package → 选择m文件(可以多个) → 填写jar名称, 类名 → Package

如下几点需要特别关注下:

  • m文件的名称就是方法的名称
  • 官方推荐使用导出的jar需要运行在JRE1.7, 笔者运行在JRE1.8未发现问题(有待验证)
  • 打包失败, 排除m文件语法错误; 最可能的原因是授权问题, 重新找个crack吧.

搭建 MCR(Matlab Compiler Runtime)

该运行环境免费, 可以到官网进行下载; 但必须下载你Matlab对应的版本和环境(x86/x64).

地址: https://cn.mathworks.com/products/compiler/matlab-runtime.html

win7

直接安装, 环境变量都会由其自动添加; 俗称一键解决.

centOS(6/7)

安装完成后, 会出现successful字样, 之后还会提醒去添加环境变量; 放在/etc/profile~/.bash_profile; 根据情况而定

变量如下:

1
2
3
MCR_ROOT=你的安装目录
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MCR_ROOT/v83/runtime/glnxa64:$MCR_ROOT/v83/bin/glnxa64:$MCR_ROOT/v83/sys/os/glnxa64
export XAPPLRESDIR=$MCR_ROOT/v83/X11/app-defaults

如此配置后, 发现yum无法使用, 异常报python版本问题, 解决方案如下:

1
2
# 修改环境变量
export LD_LIBRARY_PATH=/usr/lib64:$LD_LIBRARY_PATH:$MCR_ROOT/v83/runtime/glnxa64:$MCR_ROOT/v83/bin/glnxa64:$MCR_ROOT/v83/sys/os/glnxa64

调用

拟合算法入参: Double[n][m]

Scala中二维数组和Java中的二维数组签名并不一致, 我用了个适配方案:

  • 在Scala中使用Java独有的数据结构(在Scala中可用, 如: java.util.ArrayList)存储相关数据
  • 在Java中再将其转换为Java的二维数组, 调用Matlab生成的jar中的方法获取结果

因此, 项目中src结构如下, 相关文件按类型进行存放

1
2
3
4
5
6
7
8
9
 src
│   ├── main
│   │   ├── java
│   │   ├── resources
│   │   └── scala
│   └── test
│   ├── java
│   ├── resources
│   └── scala

jar包使用需要注意如下几点:

  • 生成的jar包必须放到classpath下, 即: 该包需要在项目启动时, load进JVM中; 后续会发博文详解使用SBT进行不同环境打包及如何使用本地仓库.
  • 除了要加入上述包, 还需要加入MCR运行包, 其位置在<mcr_root>*\toolbox\javabuilder\jar\glnxa64\javabuilder.jar, 根据不同环境进行选择

调用方式示例

1
2
3
4
5
6
double[][] array = new double[m][n];
... 涉密, 略去初始化数据和相关业务名称
MWNumericArray a = new MWNumericArray(array, MWClassID.DOUBLE);

AnalyseXXX o = new AnalyseXXX();
Object[] obj = o.xxxFun(1, a);

以上示例主要说明, 如何调用方法, xxxFun(1, a)有两个参数, 当然支持多个参数; 第一个1代表返回值有1个; 第二个参数就是实践需要传入的实参(本例为一个二维数组).

调用失败及解决方案

缺少libXmu.so链接库

java.lang.LinkageError: libXmu.so.6: cannot open shared object file: No such file or directory

直接安装就ok,

yum -y install libXmu.{i686,x86_64}

开发环境ok(OSX), 测试环境报有些方法调用失败(Linux)

总结: 专包专用

各平台的javabuilder.jar和导出的*.jar不可跨平台使用.

参考资料

转载

本文出自<<arccode>>, 欢迎转载, 转载请注明出处.