之前的文章已经介绍:
1、二次规划问题MATLAB求解器quadprog;
2、二次规划问题的基本概念;
3、二次规划求解器quadprog的win平台下C++动态库生成
本篇文章,主要介绍quadprog动态库的接口与使用
一、matlab函数接口
%没有等式约束的标准二次规划问题
function X = C_QUADPROG(H,g,A_cons,b_cons,lb,ub)
%C_QUADPROG 输入六个参数,假设没有等式约束,即Aeq = [] 和 beq = []
X = quadprog(H,g,A_cons,b_cons,[],[],lb,ub);
end
二、动态库头文件解析
头文件包含2类接口,共6个函数,分别是一般接口和功能接口。
(一)一般接口
extern LIB_C_QUADPROG_C_API
bool MW_CALL_CONV C_QUADPROGInitializeWithHandlers(
mclOutputHandlerFcn error_handler,
mclOutputHandlerFcn print_handler);
extern LIB_C_QUADPROG_C_API
bool MW_CALL_CONV C_QUADPROGInitialize(void);
extern LIB_C_QUADPROG_C_API
void MW_CALL_CONV C_QUADPROGTerminate(void);
extern LIB_C_QUADPROG_C_API
void MW_CALL_CONV C_QUADPROGPrintStackTrace(void);
(二)功能接口
function X = C_QUADPROG(H,g,A_cons,b_cons,lb,ub)
//mlx接口
bool MW_CALL_CONV mlxC_QUADPROG(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[]);
//输入参数nlhs和nrhs分别表示输入参数个数和输出参数个数;指针plhs和prhs分别指向输出矩阵和输入参数矩阵的头指针。
//mlf接口,除了int nargout, mxArray** X外,其他参数与M文件趋同
bool MW_CALL_CONV mlfC_QUADPROG(int nargout, mxArray** X, mxArray* H, mxArray* g, mxArray* A_cons, mxArray* b_cons, mxArray* lb, mxArray* ub);
//int nargout输出参数的个数,mxArray** X输出向量
(三)数据类型
MATLAB外部接口技术:https://www.jianshu.com/p/cbdc290c67f7
mxarray和mwarry数据类型详解:https://blog.csdn.net/u010329292/article/details/75005281
mxarray和mwarry数据类型使用:https://blog.csdn.net/m0_46577050/article/details/121647463
C代码比较详细:https://blog.csdn.net/qq_41990294/article/details/109437031
外部编程语言与Matlab进行交互的时候,有两个常用的数据类型接口:mxArray(C语言)和mwArray(C++语言)。两种数据类型,主要在声明、销毁、变量传递有区别。
①mxArray(C语言)
1)声明
#include "matrix.h"
mxArray *a;
2)销毁
mxDestroyArray a;
3)变量传递
mxArray *dest_ptr =mxCreateDoubleMatrix(rows,cols, mxREAL);
memcpy(dest_ptr,source_ptr,MAX_SIZE);//
//double H[3][3] = { {1,-1,1},{-1,2,-2},{1,-2,4} };
//memcpy(mxGetPr(Input_H), (void*)H, sizeof(H));
//1、mxGetPr:获取mxarray类型,目标矩阵地址
//2、(void*):获取源数据矩阵地址
//3、sizeof:获取源数据矩阵的字节大小
4)变量输出
mlfDisplay_mat(1,&mxB,mxA);
//
double Result = mxGetScalar(mxB);
//mxGetScalar来获取输入变量的数值
printf("%f\n", Result);
②mwArray(C++语言)
1)声明
mwArray a;
2)销毁
mwArray类的析构函数自动销毁对象
3)变量传递
mwArray in1(rows, cols, mxDOUBLE_CLASS, mxREAL);
mwArray in2(rows, cols, mxDOUBLE_CLASS, mxREAL);
in1.SetData(data, rows*cols);
in2.SetData(data, rows*cols);
//例如:
int a[6] = {1,2,3,4,5,6}
mwArray A(2,3,mxINT32_CLASS);
A.SetData(a,6); //第二个参数为要设置的数的个数,大小可设为rows*cols
//数据类型:
typedef enum
{
mxUNKNOWN_CLASS = 0, //未知类型
mxCELL_CLASS, //细胞类型
mxSTRUCT_CLASS, //结构类型
mxLOGICAL_CLASS, //布尔类型
mxCHAR_CLASS, //字符串类型
mxVOID_CLASS, //void类型
mxDOUBLE_CLASS,
mxSINGLE_CLASS, //单精度浮点数
mxINT8_CLASS, //
mxUINT8_CLASS,
mxINT16_CLASS,
mxUINT16_CLASS,
mxINT32_CLASS,
mxUINT32_CLASS,
mxINT64_CLASS,
mxUINT64_CLASS,
mxFUNCTION_CLASS, //函数类型
mxOPAQUE_CLASS, //
mxOBJECT_CLASS //对象类型
}
///
double data[4] = {1.0, 2.0, 3.0, 4.0};
double x;
mwArray a(2, 2, mxDOUBLE_CLASS);
a.SetData(data, 4);
x = (double)a(1,1);
x = (double)a(1,2);
x = (double)a(2,1);
x = (double)a(2,2);
三、C++主程序调用
主函数流程:
初始化应用程序–>初始化动态库–>算法操作—>关闭动态链接库–>关闭应用程序
(一)一般接口使用
①初始化应用程序
//初始化DLL动态连接文件
mclmcrInitialize();
// 鉴定Matlab外部调用环境设置是否正确.
if (!mclInitializeApplication(NULL, 0)) {
cout << "error1" << endl;
return -1;
}
②初始化动态链接库
C_QUADPROGInitialize();
if (!C_QUADPROGInitialize()) {
cout << "error2" << endl;
return -1;
}
③关闭动态链接库
C_QUADPROGTerminate(); //结束DLL库
④关闭应用程序
mclTerminateApplication();
(二)功能接口使用
①matlab接口
//matlab函数接口
function X = C_QUADPROG(H,g,A_cons,b_cons,lb,ub)
②mlx接口
//mlx接口
bool MW_CALL_CONV mlxC_QUADPROG(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[]);
//输入参数nlhs和nrhs分别表示输入参数个数和输出参数个数;指针plhs和prhs分别指向输出矩阵和输入参数矩阵的头指针。
mxArray* Input[6] = { Input_H, Input_g, Input_A, Input_b, Input_lb, Input_ub };
mxArray* Output[2];
//调用Matlab中的函数 function [x, fval] = QUADASSINPROG(H, C, A, b, lb)以测试
mlxC_QUADPROG( 1, Output, 6, Input);
//为QUADASSINPROG函数创建输出参数指针
mxArray* x = mxCreateDoubleMatrix(1, 3, mxREAL); //输出的x的大小也要随输入矩阵的大小更改
//mxArray* fval = mxCreateDoubleMatrix(1, 1, mxREAL);
//将输出参数传递给输出参数指针
x = Output[0];
③mlf接口
//mlf接口,除了int nargout, mxArray** X外,其他参数与M文件趋同
bool MW_CALL_CONV mlfC_QUADPROG(int nargout, mxArray** X, mxArray* H, mxArray* g, mxArray* A_cons, mxArray* b_cons, mxArray* lb, mxArray* ub);
//int nargout输出参数的个数,mxArray** X输出向量
//参考:
#include <stdio.h>
#include <math.h>
#include "libPkg.h" //编译建立的库头文件
main( int argc, char **argv )
{
mxArray *N; /* 输入变量矩阵指针 */
mxArray *R = NULL; /* 结果矩阵指针 */
int n; //默认的M文件输入变量数值
/* 获取命令行参数,如果命令行输入小于2,则输入参数默认为5 */
if (argc >= 2) {
n = atoi(argv[1]);
} else {
n = 5;
}
//初始化MCR和libPkg函数库
mclInitializeApplication(NULL,0);
libPkgInitialize();
/* 得到输入参量的数值 */
N = mxCreateDoubleScalar(n);
/*调用magicCreat.m编译后的文件mlfMagicCreat*/
mlfMagicCreat(1, &R, N);
/* 释放内存空间*/
mxDestroyArray(N);
mxDestroyArray(R);
//结束libPkg库和MCR
libPkgTerminate();
mclTerminateApplication();
}