MATLAB中概率密度函数直接计算正常但积分报错的问题咨询
定义概率密度函数:
$$f(y) = a0L_0 + a_{neg}\exp(A_{neg}y)L_{neg} + a_{pos}\exp(-A_{pos}(2-y))*L_{pos}$$
其中 $0<y<2$,各参数维度:
- a0:标量
- $L_0$:1×5向量
- $a_{neg}$:1×3向量
- $A_{neg}$:3×3矩阵
- $L_{neg}$:3×5矩阵
- $L_{pos}$:1×5向量
- $a_{pos}$:标量
- $A_{pos}$:标量
循环计算每个y值时代码可正常运行:
% Define the function f = @(y) a0*L_0 + a_neg*expm(A_neg * y)*L_neg + a_pos*exp(-A_pos * (2-y))*L_pos; % Define the range of y y = linspace(0, 2, 1000); % 1000 points between 0 and 2 % Initialize result matrix result = zeros(length(y), 5); % Compute the function for all y values for i = 1:length(y) result(i, :) = f(y(i)); end % Print the result disp(result);
但使用integral函数计算[1,2]区间积分(期望得到1×5向量结果)时,执行以下代码:
f_integral = integral(@(y) sum(f(y)), 0, 2);
出现错误提示:
Incorrect dimensions for matrix multiplication. Check that the number of columns in the first matrix matches the number of rows in the second matrix. To perform elementwise multiplication, use '.*'.
疑问:为何循环计算时无报错,积分时却出现维度问题?求原因及解决方法。
原因分析
循环正常的核心原因
循环中每次传入的y(i)是标量,此时所有矩阵运算的维度完全匹配:
A_neg * y(i)为3×3矩阵(标量与矩阵相乘,维度不变),expm(A_neg * y(i))输出3×3矩阵;a_neg(1×3)与该3×3矩阵相乘得到1×3向量,再与L_neg(3×5)相乘得到1×5向量;- 另外两项
a0*L_0和a_pos*exp(-A_pos*(2-y(i)))*L_pos也都是1×5向量,三者相加结果为1×5向量,与result(i,:)维度匹配,因此无报错。
积分报错的核心原因
integral函数默认采用向量化计算以提升效率,会一次性传入向量形式的y值。此时:
A_neg * y中,y是N×1向量,3×3矩阵无法直接与N×1向量进行矩阵乘法(维度不匹配);expm函数仅支持输入单个矩阵,无法处理向量输入,直接导致后续所有运算的维度混乱,最终触发报错。
另外,代码中sum(f(y))的写法也不符合需求:它会把每个y对应的1×5向量求和为标量,既无法得到期望的1×5积分结果,还会加剧维度不匹配问题。
解决方法
要得到[1,2]区间上的1×5积分结果,可采用以下两种方案:
方案一:逐维度单独积分
直接针对每个维度定义单值函数,调用integral计算标量积分,最终拼接成1×5向量:
f_integral = zeros(1, 5); for dim = 1:5 % 定义当前维度的单值积分函数 f_dim = @(y) a0*L_0(dim) + a_neg*expm(A_neg * y)*L_neg(:, dim) + a_pos*exp(-A_pos*(2-y))*L_pos(dim); % 计算该维度的积分 f_integral(dim) = integral(f_dim, 1, 2); end
方案二:支持向量化输入后逐列积分
先修改函数使其支持向量输入,输出N×5矩阵,再对每一列单独积分:
% 定义支持向量输入的函数,输出N×5矩阵(N为y的长度) f_vec = @(y) cell2mat(arrayfun(@(yi) a0*L_0 + a_neg*expm(A_neg * yi)*L_neg + a_pos*exp(-A_pos*(2-yi))*L_pos, y, 'UniformOutput', false)); % 对每个维度(列)计算积分 f_integral = arrayfun(@(dim) integral(@(y) f_vec(y)(:, dim), 1, 2), 1:5);
这里arrayfun对每个y元素单独计算,cell2mat将结果拼接成矩阵,最后逐列调用integral得到各维度积分值。
内容的提问来源于stack exchange,提问作者nemo92world

