You can check a proposed solution for weights by using your code in your original post. A function that does this is
function check_answer(matrixArray, weightArray)
L = length(matrixArray)
m, n = size(matrixArray[1])
averageMatrix = sum(matrixArray[i]*weightArray[i] for i in 1:L)/L
matrixAveragePre = accumulate(+, averageMatrix[i,j] for i in 1:m, j in 1:n)
matrixAveragePost = matrixAveragePre[m,n]/(m*n)
return matrixAveragePost
end
If I have
matrices = [
[1 2; 5 8],
[5 7; 9 0],
[4 5; 7 8],
]
and wA = [1,2,8]
I get check_answer(matrices, wA ) = 20.833
… as expected.
If I use the answer wA = [7.604777427, 2.606567535, 3.677612558]
, then I get
check_answer(matrices, wA ) = 22.0564
… so not really an answer if wanting to approximate 30.
Using wA = [1.8750000000249656, 264.0458596788466, 1.875000000025152]
I get 468.330… but this is because Oscar’s answer is solving a slightly different problem. Your problem is more like
using JuMP, Ipopt
model = Model(Ipopt.Optimizer)
matrices = [
[1 2; 5 8],
[5 7; 9 0],
[4 5; 7 8],
]
m, n = size(matrices[1])
@variable(model, 0 <= weights[1:length(matrices)])
@expression(model, X, sum(weights[i] * matrices[i] for i in 1:length(matrices)))
## New: The next line does the same as the "matrixAveragePre = accumulate(+, ..." line
@expression(model, Y, sum(X[i,j] for i in 1:m for j in 1:n))
## total objective with averaging denominator 3 and 4 respectively dividing Y:
@objective(model, Min, (30 - Y/(3*4))^2)
optimize!(model)
value.(weights)
Typing Y
in the REPL returns 16 weights[1] + 21 weights[2] + 24 weights[3]
, and a solution of weights this expression approximately equals 30*3*4 = 360.
With this in mind, it should be clear that the problem does not have a unique solution, e.g.
check_answer(matrices, [1.25906 2.06343 12.3551] ) = 29.999...
check_answer(matrices, [ 11.0037 3.51295 4.5904 ] ) = 30.000...