Matlab传入数组并拆分为多个参数传入另一个函数

        问题背景:在Matlab编写一个函数(如FunManage(fun,params)函数)时,通过函数调用另外一个函数@fun(假设fun的参数是a,b,c), 并通过一个数组接受params, 经过一定的处理后,将params数组拆分成多个参数,传入fun函数中再次调用得到结果

        在Matlab编程过程中,常常会遇到需要传入函数和参数的问题:如类似python中的arg**项传入不定项参数等等,这里我以我需要编写的求解梯度的算法为例(这个我是仿python里mxnet包的autograd函数,用来求解梯度的):

基本原理是转换为字符串执行

示例

        1. 主函数(调用)

        使用autograd求解cos(x*y)在x = pi/6 , y = pi/3 处对x的梯度(第三个参数是指定求梯度的参数位置,第四个是指定步长)

        其中使用@函数句柄将函数传入

autograd(@fun, [pi/6, pi/3], 1, 0.01)

function out = fun(x,y)
out = cos(x* y);
end
% 求解cos(x,y)在(pi/6, pi/3)对x的梯度
% \partial fun / \partial x = y * -sin(x * y)

% 注意: [pi/6, pi/3] 是以数组形式输入的多个参数,在autograd中将拆分后用fun进行调用

       

         2. autograd函数

        在autograd函数中,使用split将参数用逗号分隔开,再用eval函数来将字符串执行相应的语句(其中join是拼接字符串,join的第二的参数指定拼接无间隔(默认使用空格进行拼接))

function grad = autograd(func, param, argNum, optional_dx)
    % func 为需要求解梯度的函数, params作为参数传入, argNum标识参数的位置,
    if nargin == 3
        optional_dx = 0.01 * param(argNum);
    end
    param_str = join(split(string(param)),',');

    eval(join(['y0 = func(', param_str ,');'],''));

    param2 = param;   % 新赋一个值,防止由于函数修改堆中的数据导致的原始数组改变
    param2(argNum) = param(argNum) + optional_dx;

    param2_str = join(split(string(param2)),',');
    eval(join(['y1 = func(', param2_str ,');'],''));
    grad = ( y1 -y0 ) / optional_dx ;
    
end

% 定义autograd函数求解损失函数对于相应自变量的梯度
% 使用最简单的思路,将自变量增加一个微小的值,再使用函数计算出函数的变化值
% 使用函数变化值 - 自变量的变化值作为相应的点的梯度

得到的结果是-0.5505, 我计算了一下cos(x*y)对x的偏导数- y* sin(x*y ), 代入x = pi/6, y = pi/3,得到的结果是-0.545848449

这个只需要在主函数中缩小下步长参数origional_dx就行了

当然也是一种近似求解偏导数的方法

至于这个应用的话,可以有和python中的arg**类似的功用

其实国庆事情挺多的,估计还得接着使劲鸽(这篇文章不长就算成是水水吧)

猜你喜欢

转载自blog.csdn.net/sbsbsb666666/article/details/127218060
今日推荐