From a6098fd084bb919ffba1a1eab09ed862a6318e42 Mon Sep 17 00:00:00 2001 From: odow Date: Fri, 3 Nov 2023 14:11:36 +1300 Subject: [PATCH] Improve error message for non-broadcasted addition and subtraction --- src/operators.jl | 37 +++++++++++++++++++--------- test/test_operator.jl | 56 +++++++++++++++++++------------------------ 2 files changed, 50 insertions(+), 43 deletions(-) diff --git a/src/operators.jl b/src/operators.jl index 608dacc5028..76a06742e2e 100644 --- a/src/operators.jl +++ b/src/operators.jl @@ -452,22 +452,37 @@ function LinearAlgebra.issymmetric(x::Matrix{T}) where {T<:_JuMPTypes} return true end -function Base.:+(A::AbstractMatrix, x::AbstractJuMPScalar) +function _throw_operator_error(::Union{typeof(+),typeof(_MA.add_mul)}) return error( - "Addition between a Matrix and a JuMP variable is not supported: instead of `A + x`, " * - "do `A .+ x` for element-wise addition, or if you are modifying the diagonal entries of the matrix " * - "do `A + x * LinearAlgebra.I(n)`, where `n` is the diagonal length.", + "Addition between an array and a JuMP scalar is not supported: " * + "instead of `x + y`, do `x .+ y` for element-wise addition.", ) end -Base.:+(x::AbstractJuMPScalar, A::AbstractMatrix) = A + x - -function Base.:-(A::AbstractMatrix, x::AbstractJuMPScalar) +function _throw_operator_error(::Union{typeof(-),typeof(_MA.sub_mul)}) return error( - "Subtraction between a Matrix and a JuMP variable is not supported: instead of `A - x`, " * - "do `A .- x` for element-wise subtraction, or if you are modifying the diagonal entries of the matrix " * - "do `A - x * LinearAlgebra.I(n)`, where `n` is the diagonal length.", + "Subtraction between a Matrix and a JuMP scalar is not supported: " * + "instead of `x - y`, do `x .- y` for element-wise subtraction.", ) end -Base.:-(x::AbstractJuMPScalar, A::AbstractMatrix) = A - x +Base.:+(::AbstractJuMPScalar, ::AbstractMatrix) = _throw_operator_error(+) +Base.:+(::AbstractMatrix, ::AbstractJuMPScalar) = _throw_operator_error(+) +Base.:-(::AbstractJuMPScalar, ::AbstractMatrix) = _throw_operator_error(-) +Base.:-(::AbstractMatrix, ::AbstractJuMPScalar) = _throw_operator_error(-) + +function _MA.operate!!( + op::Union{typeof(_MA.add_mul),typeof(_MA.sub_mul)}, + ::AbstractArray, + ::AbstractJuMPScalar, +) + return _throw_operator_error(op) +end + +function _MA.operate!!( + op::Union{typeof(_MA.add_mul),typeof(_MA.sub_mul)}, + ::AbstractJuMPScalar, + ::AbstractArray, +) + return _throw_operator_error(op) +end diff --git a/test/test_operator.jl b/test/test_operator.jl index 4f43a05891a..9bcea576b46 100644 --- a/test/test_operator.jl +++ b/test/test_operator.jl @@ -629,38 +629,30 @@ function test_matrix_abstractscalar_add() model = Model() @variable(model, x) A = rand(Float64, 2, 2) - @test_throws( - ErrorException( - "Addition between a Matrix and a JuMP variable is not supported: instead of `A + x`, " * - "do `A .+ x` for element-wise addition, or if you are modifying the diagonal entries of the matrix " * - "do `A + x * LinearAlgebra.I(n)`, where `n` is the diagonal length.", - ), - A + x - ), - @test_throws( - ErrorException( - "Addition between a Matrix and a JuMP variable is not supported: instead of `A + x`, " * - "do `A .+ x` for element-wise addition, or if you are modifying the diagonal entries of the matrix " * - "do `A + x * LinearAlgebra.I(n)`, where `n` is the diagonal length.", - ), - x + A - ), - @test_throws( - ErrorException( - "Subtraction between a Matrix and a JuMP variable is not supported: instead of `A - x`, " * - "do `A .- x` for element-wise subtraction, or if you are modifying the diagonal entries of the matrix " * - "do `A - x * LinearAlgebra.I(n)`, where `n` is the diagonal length.", - ), - A - x - ), - @test_throws( - ErrorException( - "Subtraction between a Matrix and a JuMP variable is not supported: instead of `A - x`, " * - "do `A .- x` for element-wise subtraction, or if you are modifying the diagonal entries of the matrix " * - "do `A - x * LinearAlgebra.I(n)`, where `n` is the diagonal length.", - ), - x - A - ), + err_add = ErrorException( + "Addition between an array and a JuMP scalar is not supported: " * + "instead of `x + y`, do `x .+ y` for element-wise addition.", + ) + @test_throws(err_add, A + x) + @test_throws(err_add, x + A) + @test_throws(err_add, A' + x) + @test_throws(err_add, x + A') + @test_throws(err_add, @expression(model, A + x)) + @test_throws(err_add, @expression(model, x + A)) + @test_throws(err_add, @expression(model, A' + x)) + @test_throws(err_add, @expression(model, x + A')) + err_sub = ErrorException( + "Subtraction between a Matrix and a JuMP scalar is not supported: " * + "instead of `x - y`, do `x .- y` for element-wise subtraction.", + ) + @test_throws(err_sub, A - x) + @test_throws(err_sub, x - A) + @test_throws(err_sub, A' - x) + @test_throws(err_sub, x - A') + @test_throws(err_sub, @expression(model, A - x)) + @test_throws(err_sub, @expression(model, x - A)) + @test_throws(err_sub, @expression(model, A' - x)) + @test_throws(err_sub, @expression(model, x - A')) return end