Matlab中特定函数f(x)梯度求解结果异常问题咨询
Fixing the Gradient Calculation for Your MATLAB Optimization Function
Let's walk through where your current code goes wrong, then derive the correct analytical gradient and implement it properly.
First, Clarify the Function & Dimensions
Your objective function is:
$$f(x) = c^T x - \sum_{i=1}^m \log\left(b_i - a_i^T x\right)$$
Based on your description (n=2, m=20):
- To align with the sum of 20 terms, $A$ should be an m×n (20×2) matrix, where each row is the $a_i^T$ vector (1×2). This matches the size of $b$ (20×1), so $b_i - a_i^T x$ is a valid scalar for each $i$. Your original dimension note said $A$ is n×m, which likely caused confusion in your code.
What's Wrong with Your Current Code?
- Incorrect Loop Range: You're looping over the rows of $A$ (only 2 times for n=2), but you need to account for all 20 terms in the sum.
- Dimension Mismatch: $A(k,:)'*x(k)$ produces an n×1 vector, but $b$ is m×1—subtracting these either throws an error or generates invalid values via unintended implicit expansion.
- Misuse of
gradient(): MATLAB'sgradient()computes a numerical gradient over an array, but you need an analytical gradient derived directly from the function's math. Using it here is unnecessary and will give wrong results.
Correct Analytical Gradient Derivation
Let's compute $\nabla f(x)$ (the n×1 gradient vector):
- The gradient of $c^T x$ with respect to $x$ is simply $c$ (standard linear term derivative).
- For the sum term: $\frac{\partial}{\partial x_j} \left( -\sum_{i=1}^m \log(b_i - a_i^T x) \right) = \sum_{i=1}^m \frac{a_{i,j}}{b_i - a_i^T x}$, where $a_{i,j}$ is the j-th element of $a_i^T$.
- Combining both parts, the full gradient in matrix form (perfect for MATLAB vectorization):
$$\nabla f(x) = c + A^T \cdot \left( \frac{1}{b - A x} \right)$$
(Here, $A x$ gives an m×1 vector, element-wise division by $b - A x$ gives an m×1 reciprocal vector, and multiplying by $A^T$ (n×m) gives an n×1 gradient matching $c$'s size.)
Fixed MATLAB Code
function gc0 = gc(x, c, b, A) % Compute the argument inside the log (m×1 vector) log_argument = b - A * x; % Calculate element-wise reciprocals (m×1 vector) reciprocal_terms = 1 ./ log_argument; % Compute the sum term using matrix multiplication (n×1 vector) sum_gradient = A' * reciprocal_terms; % Combine to get the final gradient gc0 = c + sum_gradient; end
Key Notes on the Fixed Code:
- No loops needed! MATLAB's vectorized operations are faster and less error-prone than explicit loops for this calculation.
- All dimensions align perfectly: 20×2 matrix $A$ multiplied by 2×1 vector $x$ gives a 20×1 vector, which subtracts cleanly from $b$ (20×1). Transposing $A$ to 2×20 and multiplying by the 20×1 reciprocal vector gives a 2×1 result that adds to $c$ (2×1).
- Ensure
log_argumentis strictly positive (required for the original function to be defined) to avoid numerical errors.
内容的提问来源于stack exchange,提问作者user6058265
相关产品推荐
相关产品推荐

