MindOpt APL向量化建模语法的介绍与应用(1)

本文介绍了MindOptAPL如何支持向量化建模,包括常量参数声明、张量常量表达式计算、矩阵和向量操作,以及在实际问题中的应用,如线性支持向量机建模。作者通过详细讲解语法和示例展示了如何利用这些特性提高计算效率和问题解决的灵活性。
摘要由CSDN通过智能技术生成

简介

向量化建模是一种高效的数学建模和编程技术,它涉及到对向量、矩阵和更高维数组进行操作,以实现操作的同时性和批量处理。在优化和数据分析等领域,向量化建模可以极大地提高计算效率,特别是当涉及到大量的重复计算时。由于向量化建模具有表述优势、操作优势、计算性能、可扩展性等优势,使得其适合于解决很大一类实际问题

MindOpt APL (MindOpt Algebraic Programming Language, MAPL) 是一种高效且通用的代数建模语言,主要用于数学规划问题的建模,并支持调用多种求解器求解。它当前支持通用的线性、非线性、混合整数问题的建模。其语法贴近数学语言,与代数数学公式很接近,易学易写易读易维护。且MindOpt APL支持对接20+种优化求解器,可用一行命令就切换,大大提升了用户在优化问题求解环节的方案丰富度,降低风险和使用门槛。

那么MAPL是如何支持向量化建模的呢,让我们一起来看下文

MAPL中的向量化建模

MAPL通过对向量/矩阵常量参数与变量的声明以及运用张量常量表达式的计算、向量/矩阵变量表达式的计算对问题进行建模

本篇我们介绍述向量/矩阵常量参数的声明以及运用张量常量表达式的计算的语法

其中常量参数的声明有三种方式

  • 显式定义常量参数

声明一个 m × n m\times n m×n的矩阵式常量:
param matrix_name = [A_11, , A_1n (n个实数) ; … (m行)A_n1, … , A_mn (n个实数) ];

声明一个 1 × m 1\times m 1×m向量式常量:
param vector_name = [a_11, **… , a_1n (n个实数) ];

  • 使用MAPL的内置函数生成常量参数

    param v = 内置函数名([param_list]);

  • 从表格式csv文件中读取矩阵形式的常量参数

    param v = read_csv([file_name,] [param_list]);


张量常量表达式的数学运算符列表如下:

类型操作符说明是否支持标量用例
一元操作符+向量/矩阵加法A+B
-向量/矩阵减法,或者参数求反A-B or -A
.*逐元素乘法A.*B
./逐元素除法A./B
*向量/矩阵乘法A*B
'矩阵转置A'
/向量/矩阵逐元素除以某标量A/2
二元操作符.^逐元素的p次幂A.^2
^逐元素的p次幂A^2
索引操作符[]获取指定位置的值A[3,5]

其中“支持标量”的操作符,不仅可以支持标量间或者张量间的常规计算,也能以某种方式实现标量与张量之间的混合计算,浏览文档查看

语法示例

  1. 显式定义常量参数:通过列出所有元素的值来创建矩阵或向量。例如,声明一个 m×n 矩阵的语法是 param matrix_name = [A_11, ..., A_1n; ...; A_m1, ..., A_mn];,声明一个 1×m 向量的语法是 param vector_name = [a_1, ..., a_n];
    1. 获取参数属性:可以使用 .row.col 来获取矩阵/向量参数的行数和列数,例如获取矩阵 X的大小。
param vec = [1,3,5,7,9,11];
print "Shape of vec: ({},{})." % vec.row, vec.col;

param A =[1,2,3;
4,5,6;
7,8,9];

print "Shape of A: ({},{})." % A.row, A.col;
Shape of vec: (1,6).
Shape of A: (3,3).
  1. 参数的索引:可通过行/列号对向量/矩阵中的元素进行索引,索引从0开始。例如,对于向量 vecvec[4]vec[0,4] 都指向向量的第五个元素;对于矩阵 AA[i-1,j-1] 指向矩阵的第 i行第 j列元素。
param A =[1,2,3;
4,5,6;
7,8,9];

#遍历输出所有大于等于5的项
for (i,j) in (1..A.row) * (1..A.col):
    if A[i-1,j-1] >= 5 then print "A[{},{}]={}"%i,j,A[i-1, j-1];
A[2,2]=5
A[2,3]=6
A[3,1]=7
A[3,2]=8
A[3,3]=9

  1. 使用内置函数生成常量参数:MAPL 提供了一些内置函数如 ones, zeros, identity, randomnormal 来快速生成特定类型的向量/矩阵常量。例如,ones(3,7) 创建一个3x7的全1矩阵,random(3,7) 创建一个满足[0,1]均匀分布的3x7随机矩阵。
clear model;
print "ones matrix: ones(3,7)";
param one = ones(3,7);
print one;
print "--------------";

print "zeros matrix: zeros(3,7)"; 
param zero = zeros(3,7);
print zero;
print "--------------";

print "identity matrix: identity(4,4)";
param E = identity(4,4);
print E;
print "--------------";

print "random matrix: random(shape=(3,7), seed=12345)";
param X = random(shape=(3,7), seed=123456);
print X;
print "--------------";

print "normal matrix, (mu,sigma)=(-10,10): normal(shape=(3,7), mu=-10, sigma=10, seed=12345);";
param Y = normal(shape=(3,7), mu=-10, sigma=10, seed=123456);
print Y;
ones matrix: ones(3,7)
[[1, 1, 1, 1, 1, 1, 1],
 [1, 1, 1, 1, 1, 1, 1],
 [1, 1, 1, 1, 1, 1, 1]]
--------------
zeros matrix: zeros(3,7)
[[0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0]]
--------------
identity matrix: identity(4,4)
[[1, 0, 0, 0],
 [0, 1, 0, 0],
 [0, 0, 1, 0],
 [0, 0, 0, 1]]
--------------
random matrix: random(shape=(3,7), seed=12345)
[[0.51491, 0.89813, 0.70582, 0.77883, 0.93162, 0.62877, 0.33987],
 [0.21579, 0.11833, 0.08322, 0.38544, 0.96056, 0.94246, 0.35274],
 [0.17555, 0.15881, 0.95409, 0.14046, 0.03238, 0.84024, 0.81065]]
--------------
normal matrix, (mu,sigma)=(-10,10): normal(shape=(3,7), mu=-10, sigma=10, seed=12345);
[[ -0.47484,  -9.64320,  -0.25816,  -2.80899,  -8.15235,  -3.80674, -21.38680],
 [-16.41576,  -5.56788, -11.10240, -11.66778,  -4.98887, -13.55322, -13.37890],
 [ -4.19033,  -0.16199,  -9.42198,  -2.38052, -17.12964, -14.43160, -19.74602]]

  1. 从CSV文件中读取矩阵形式的常量参数:使用 read_csv 函数可以从CSV文件中读取数据并自动将其视为一个常量矩阵或向量。例如,param X := read_csv("iris.data", use_col="0,1,2,3", skip =1);会从 iris.data文件中读取前四列数据作为矩阵X。然后可以查询矩阵的形状信息,并通过索引访问其中的元素。
X,X,X,X,Y
5.1,3.5,1.4,0.2,1
4.9,3.0,1.4,0.2,1
4.7,3.2,1.3,0.2,1
4.6,3.1,1.5,0.2,1
5.0,3.6,1.4,0.2,1
5.7,3.0,4.2,1.2,-1
5.7,2.9,4.2,1.3,-1
6.2,2.9,4.3,1.3,-1
5.1,2.5,3.0,1.1,-1
5.7,2.8,4.1,1.3,-1
param X:= read_csv("iris.data", use_col="0,1,2,3", skip =1);
param y:= read_csv("iris.data", use_col=4,skip =1);

print "Shape of X is: ({},{})." % X.row, X.col;
print "Shape of y is: ({},{})." % y.row, y.col;

print "X[0,0] is {:.1f}" % X[0, 0];
print "X[9,2]*y[5] is {:.1f}" % X[9, 2] * y[5];
Shape of X is: (10,4).
Shape of y is: (10,1).
X[0,0] is 5.1
X[9,2]*y[5] is -4.1

表达式的计算示例(向量及矩阵乘法)更多示例

param a = [1,2,3,4,5,6,7,8,9,10];
param b = [10,9,8,7,6,5,4,3,2,1];

print "a * b' is: ", a * b';

print "b'*a is:";
print b'*a;
a * b' is: 220

b'*a is:
[[ 10,  20,  30,  40,  50,  60,  70,  80,  90, 100],
 [  9,  18,  27,  36,  45,  54,  63,  72,  81,  90],
 [  8,  16,  24,  32,  40,  48,  56,  64,  72,  80],
 [  7,  14,  21,  28,  35,  42,  49,  56,  63,  70],
 [  6,  12,  18,  24,  30,  36,  42,  48,  54,  60],
 [  5,  10,  15,  20,  25,  30,  35,  40,  45,  50],
 [  4,   8,  12,  16,  20,  24,  28,  32,  36,  40],
 [  3,   6,   9,  12,  15,  18,  21,  24,  27,  30],
 [  2,   4,   6,   8,  10,  12,  14,  16,  18,  20],
 [  1,   2,   3,   4,   5,   6,   7,   8,   9,  10]]

一个案例代码示例

线性支持向量机(Linear Support Vector Machine, SVM)是一种广泛应用于模式识别、分类以及回归问题的监督学习算法。SVM的核心思想是寻找一个最优的超平面,用以划分不同类别的数据点,同时最大化各类数据点到该超平面的最小间隔(margin)。
代码如下:

# 1.读取iris数据
param X:= read_csv("$data_path/iris.data", use_col="0,1,2,3");
param y:= read_csv("$data_path/iris.data", use_col=4);
param m = X.row;
param n = X.col;

# 2.LinearSVM问题建模
param rho = 0.2;
var w(n) >= -1 <= 1; # Bounded Model Parameter
var eps(m) >= 0;

minimize
w' * w + rho * sum(eps);
s.t.
eps >= 1 - X*w.*y;

# 3.调用开源求解器Ipopt求解
option solver ipopt;
solve;

# 4.验证并分析结果
param total_loss = rho * ones(1, m) * eps + w'*w;
param prec = 1/m * sum{i in 0..m-1} 
if (sum{j in 0..n-1} (w[j]*X[i, j])) * y[i] > 0 then 1 else 0 end;

print "(Objective, Precision): ({:.2f}, {:.1f})" % total_loss, prec;

结果查看可浏览文档,介绍更全面!

  • 15
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值