Hi, I have a use case where I need to evaluate many quadratic expressions of the form x^T M x, with the matrix M always beeing symmetric. The typical dimensionality of M is between 3 and 3000.
Using the following two approaches for computing this expresssion,
product_1(x, M) = dot(x, M, x)
function product_2(x, M)
Mx = M * x
return dot(x, Mx)
end
and when comparing Matrix{Float64}
and Symmetric{Float64, Matrix{Float64}}
matrices, I found the following performances:
I’m a bit surprised that the Symmetric
case is not always faster. Also, I’m not sure how “bad” it is to make the tradeoff between computation time and memory allocations when using product_2
for large matrices (for D=1000: 1 allocation: ~ 8 KiB, compared to 0 allocations for product_1
)
I also tried to implement this product myself, since due to the symmetry of M, only either the lower or the upper triangle of M needs to be considered. However, I have not been able to make this product as fast as the other two functions, even though I only iterate over half of the matrix.
function product_3(x, M)
n = length(x)
result = zero(eltype(x))
@inbounds for i = 1:n
result += x[i]^2 * M[i, i]
@simd for j = 1 : i - 1
result += 2* x[i] * x[j] * M[j, i]
end
end
return result
end
(product_3
is much slower and has a lot of allocations.)
Do you have any suggestions on how to get the best performance for this type of product with symmetric matrices? Is there a way around using different functions and datatypes for different sizes of M to get the best performance?