What is the best tool to use for weighting matrices

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...

2 Likes