text:
@testset "Function tests" begin
    w = MOI.VariableIndex(0)
    x = MOI.VariableIndex(1)
    y = MOI.VariableIndex(2)
    z = MOI.VariableIndex(3)
    @testset "operate vcat" begin
        v = MOI.VectorOfVariables([y, w])
        f = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([2, 4],
                                                           [x, z]), 5)
        g = MOI.VectorAffineFunction(MOI.VectorAffineTerm.([3, 1],
                                                           MOI.ScalarAffineTerm.([5, 2],
                                                                                [y, x])),
                                                           [3, 1, 4])
        wf = MOI.SingleVariable(w)
        xf = MOI.SingleVariable(x)
        @test MOIU.promote_operation(vcat, Int, typeof(wf), typeof(f),
                                     typeof(v), Int, typeof(g), typeof(xf),
                                     Int) == MOI.VectorAffineFunction{Int}
        F = MOIU.operate(vcat, Int, wf, f, v, 3, g, xf, -4)
        @test F.terms == MOI.VectorAffineTerm.([1, 2, 2, 3, 4, 8, 6, 9],
                                               MOI.ScalarAffineTerm.([1, 2, 4, 1, 1, 5, 2, 1],
                                                                     [w, x, z, y, w, y, x, x]))
        @test F.constants == [0, 5, 0, 0, 3, 3, 1, 4, 0, -4]
    end
    @testset "MultirowChange construction" begin
        chg1 = MOI.MultirowChange(w, [(Int32(2), 2.0), (Int32(1), 3.0)])
        chg2 = MOI.MultirowChange(w, [(Int64(2), 2.0), (Int64(1), 3.0)])
        @test chg1.variable == chg2.variable
        @test chg1.new_coefficients == chg2.new_coefficients
    end
    @testset "VectorAffineTerm/VectorQuadraticTerm construction" begin
        scalaraffine = MOI.ScalarAffineTerm(2.0, z)
        @test MOI.VectorAffineTerm(Int32(3), scalaraffine) === MOI.VectorAffineTerm(Int64(3), scalaraffine)
        @test MOI.VectorAffineTerm{Float64}(Int32(3), scalaraffine) === MOI.VectorAffineTerm(Int64(3), scalaraffine)
        scalarquad = MOI.ScalarQuadraticTerm(2.0, y, z)
        @test MOI.VectorQuadraticTerm(Int32(3), scalarquad) === MOI.VectorQuadraticTerm(Int64(3), scalarquad)
        @test MOI.VectorQuadraticTerm{Float64}(Int32(3), scalarquad) === MOI.VectorQuadraticTerm(Int64(3), scalarquad)
    end
    @testset "evalvariables" begin
        # We do tests twice to make sure the function is not modified
        vals = Dict(w=>0, x=>3, y=>1, z=>5)
        fsv = MOI.SingleVariable(z)
        @test MOI.output_dimension(fsv) == 1
        @test MOIU.evalvariables(vi -> vals[vi], fsv) ≈ 5
        @test MOIU.evalvariables(vi -> vals[vi], fsv) ≈ 5
        fvv = MOI.VectorOfVariables([x, z, y])
        @test MOI.output_dimension(fvv) == 3
        @test MOIU.evalvariables(vi -> vals[vi], fvv) ≈ [3, 5, 1]
        @test MOIU.evalvariables(vi -> vals[vi], fvv) ≈ [3, 5, 1]
        fsa = MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(1.0, x), MOI.ScalarAffineTerm(3.0, z), MOI.ScalarAffineTerm(2.0, y)], 2.0)
        @test MOI.output_dimension(fsa) == 1
        @test MOIU.evalvariables(vi -> vals[vi], fsa) ≈ 22
        @test MOIU.evalvariables(vi -> vals[vi], fsa) ≈ 22
        fva = MOI.VectorAffineFunction(MOI.VectorAffineTerm.([2, 1, 2], MOI.ScalarAffineTerm.([1.0, 3.0, 2.0], [x, z, y])), [-3.0, 2.0])
        @test MOI.output_dimension(fva) == 2
        @test MOIU.evalvariables(vi -> vals[vi], fva) ≈ [12, 7]
        @test MOIU.evalvariables(vi -> vals[vi], fva) ≈ [12, 7]
        fsq = MOI.ScalarQuadraticFunction(MOI.ScalarAffineTerm.(1.0, [x, y]),
                                          MOI.ScalarQuadraticTerm.(1.0, [x, w, w], [z, z, y]), -3.0)
        @test MOI.output_dimension(fsq) == 1
        @test MOIU.evalvariables(vi -> vals[vi], fsq) ≈ 16
        @test MOIU.evalvariables(vi -> vals[vi], fsq) ≈ 16
        fvq = MOI.VectorQuadraticFunction(MOI.VectorAffineTerm.([2, 1], MOI.ScalarAffineTerm.(1.0, [x, y])),
                                          MOI.VectorQuadraticTerm.([1, 2, 2], MOI.ScalarQuadraticTerm.(1.0, [x, w, w], [z, z, y])), [-3.0, -2.0])
        @test MOI.output_dimension(fvq) == 2
        @test MOIU.evalvariables(vi -> vals[vi], fvq) ≈ [13, 1]
        @test MOIU.evalvariables(vi -> vals[vi], fvq) ≈ [13, 1]
    end
    @testset "mapvariables" begin
        fsq = MOI.ScalarQuadraticFunction(MOI.ScalarAffineTerm.(1.0, [x, y]),
                                          MOI.ScalarQuadraticTerm.(1.0, [x, w, w], [z, z, y]), -3.0)
        gsq = MOIU.mapvariables(Dict(x => y, y => z, w => w, z => x), fsq)
        sats = MOI.ScalarAffineTerm.(1.0, [y, z])
        sqts = MOI.ScalarQuadraticTerm.(1.0, [y, w, w], [x, x, z])
        @test gsq.affine_terms == sats
        @test gsq.quadratic_terms == sqts
        @test gsq.constant == -3.
        fvq = MOI.VectorQuadraticFunction(MOI.VectorAffineTerm.([2, 1], MOI.ScalarAffineTerm.(1.0, [x, y])),
                                          MOI.VectorQuadraticTerm.([1, 2, 2], MOI.ScalarQuadraticTerm.(1.0, [x, w, w], [z, z, y])), [-3.0, -2.0])
        gvq = MOIU.mapvariables(Dict(x => y, y => z, w => w, z => x), fvq)
        @test gvq.affine_terms == MOI.VectorAffineTerm.([2, 1], sats)
        @test gvq.quadratic_terms == MOI.VectorQuadraticTerm.([1, 2, 2], sqts)
        @test MOIU.constant(gvq) == [-3., -2.]
    end
    @testset "Conversion VectorOfVariables -> VectorAffineFunction" begin
        f = MOI.VectorAffineFunction{Int}(MOI.VectorOfVariables([z, x, y]))
        @test f isa MOI.VectorAffineFunction{Int}
        @test f.terms == MOI.VectorAffineTerm.(1:3, MOI.ScalarAffineTerm.(ones(Int, 3), [z, x, y]))
        @test all(iszero.(MOIU.constant(f)))
        f = MOI.VectorAffineFunction{Float64}(MOI.VectorOfVariables([x, w]))
        @test f isa MOI.VectorAffineFunction{Float64}
        @test f.terms == MOI.VectorAffineTerm.(1:2, MOI.ScalarAffineTerm.(1.0, [x, w]))
        @test all(iszero.(MOIU.constant(f)))
    end
    @testset "Iteration and indexing on VectorOfVariables" begin
        f = MOI.VectorOfVariables([z, w, x, y])
        it = MOIU.eachscalar(f)
        @test length(it) == 4
        @test eltype(it) == MOI.SingleVariable
        @test collect(it) == [MOI.SingleVariable(z), MOI.SingleVariable(w), MOI.SingleVariable(x), MOI.SingleVariable(y)]
        @test it[2] == MOI.SingleVariable(w)
        @test it[end] == MOI.SingleVariable(y)
    end
    @testset "Indexing on VectorAffineFunction" begin
        f = MOI.VectorAffineFunction(MOI.VectorAffineTerm.([2, 1, 3, 2, 2, 1, 3, 1, 2],
                                                           MOI.ScalarAffineTerm.([1, 7, 2, 9, 3, 1, 6, 4, 1],
                                                                                [x, y, z, z, y, z, x, x, y])),
                                     [2, 7, 5])
        it = MOIU.eachscalar(f)
        @test length(it) == 3
        @test eltype(it) == MOI.ScalarAffineFunction{Int}
        g = it[2]
        @test g isa MOI.ScalarAffineFunction
        @test g.terms == MOI.ScalarAffineTerm.([1, 9, 3, 1], [x, z, y, y])
        @test g.constant == 7
        g = it[1]
        @test g isa MOI.ScalarAffineFunction
        @test g.terms == MOI.ScalarAffineTerm.([7, 1, 4], [y, z, x])
        @test g.constant == 2
        g = it[end]
        @test g isa MOI.ScalarAffineFunction
        @test g.terms == MOI.ScalarAffineTerm.([2, 6], [z, x])
        @test g.constant == 5
        h = it[[3, 1]]
        @test h isa MOI.VectorAffineFunction
        @test h.terms == MOI.VectorAffineTerm.([1, 1, 2, 2, 2], MOI.ScalarAffineTerm.([2, 6, 7, 1, 4], [z, x, y, z, x]))
        @test MOIU.constant(h) == [5, 2]
        F = MOIU.operate(vcat, Int, it[[1, 2]], it[3])
        @test F isa MOI.VectorAffineFunction{Int}
        @test F.terms == MOI.VectorAffineTerm.([1, 1, 1, 2, 2, 2, 2, 3, 3], MOI.ScalarAffineTerm.([7, 1, 4, 1, 9, 3, 1, 2, 6], [y, z, x, x, z, y, y, z, x]))
        @test MOIU.constant(F) == MOIU.constant(f)
    end
    @testset "Indexing on VectorQuadraticFunction" begin
        f = MOI.VectorQuadraticFunction(MOI.VectorAffineTerm.([2, 1, 3, 2, 2],
                                                              MOI.ScalarAffineTerm.([1, 7, 2, 9, 3],
                                                                                [x, y, z, z, y])),
                                        MOI.VectorQuadraticTerm.([2, 3, 1, 2],
                                                                 MOI.ScalarQuadraticTerm.([1, 6, 4, 3],
                                                                                [z, x, x, y],
                                                                                [y, z, z, y])),
                                        [2, 7, 5])
        it = MOIU.eachscalar(f)
        @test length(it) == 3
        @test eltype(it) == MOI.ScalarQuadraticFunction{Int}
        g = it[2]
        @test g isa MOI.ScalarQuadraticFunction
        @test g.affine_terms == MOI.ScalarAffineTerm.([1, 9, 3], [x, z, y])
        @test g.quadratic_terms == MOI.ScalarQuadraticTerm.([1, 3], [z, y], [y, y])
        @test g.constant == 7
        g = it[end]
        @test g isa MOI.ScalarQuadraticFunction
        @test g.affine_terms == MOI.ScalarAffineTerm.([2], [z])
        @test g.quadratic_terms == MOI.ScalarQuadraticTerm.([6], [x], [z])
        @test g.constant == 5
    end
    @testset "Scalar" begin
        @testset "Affine" begin
            @testset "promote_operation" begin
                @test MOIU.promote_operation(+, Float64, MOI.SingleVariable,
                                             MOI.SingleVariable) == MOI.ScalarAffineFunction{Float64}
                @test MOIU.promote_operation(+, Float64,
                                             MOI.ScalarAffineFunction{Float64},
                                             Float64) == MOI.ScalarAffineFunction{Float64}
                @test MOIU.promote_operation(+, Int,
                                             MOI.ScalarAffineFunction{Int},
                                             MOI.ScalarAffineFunction{Int}) == MOI.ScalarAffineFunction{Int}
            end
            @testset "Comparison tolerance" begin
                @test MOIU.operate(+, Float64, MOI.SingleVariable(x),
                                   MOI.SingleVariable(z)) + 1.0 ≈
                      MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1, 1e-7, 1], [x, y, z]), 1.0) atol=1e-6
                f1 = MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(1.0, x), MOI.ScalarAffineTerm(1e-7, y)], 1.0)
                f2 = MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(1.0, x)], 1.0)
                @test f1 ≈ f2 atol=1e-6
                fdiff = f1 - f2
                MOIU.canonicalize!(fdiff)
                @test !MOIU.isapprox_zero(fdiff, 1e-8)
                @test MOIU.isapprox_zero(fdiff, 1e-6)
            end
            @testset "canonical" begin
                f = MOIU.canonical(MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([2, 1, 3, -2, -3], [y, x, z, x, z]), 5))
                @test MOI.output_dimension(f) == 1
                @test f.terms == MOI.ScalarAffineTerm.([-1, 2], [x, y])
                @test f.constant == 5
                f = MOIU.canonical(MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1, 3, 1, 2, -3, 2],
                                                                                [w, y, w, x,  x, z]), 2) +
                                   MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([-1, -2, -2, 3, 2],
                                                                                [ y,  z,  w, x, y]), 3))
                @test f.terms == MOI.ScalarAffineTerm.([2, 4], [x, y])
                @test f.constant == 5
            end
            f = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([2, 4], [x, y]),
                                         5)
            @testset "convert" begin
                @test_throws InexactError convert(MOI.SingleVariable, f)
                quad_f = MOI.ScalarQuadraticFunction(f.terms,
                                                     MOI.ScalarQuadraticTerm{Int}[],
                                                     f.constant)
                @test convert(MOI.ScalarQuadraticFunction{Int}, f) ≈ quad_f
                g = convert(MOI.ScalarAffineFunction{Float64}, MOI.SingleVariable(x))
                @test convert(MOI.SingleVariable, g) == MOI.SingleVariable(x)
            end
            @testset "operate" begin
                f = MOIU.canonical(MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1, 3, 1, 2, -3, 2],
                                                                                [w, y, w, x,  x, z]), 2) +
                                   MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([-1, -2, -2, 3, 2],
                                                                                [ y,  z,  w, x, y]), 3))
                @test f ≈ MOI.SingleVariable(x) + MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1, 4],
                                                                                [x, y]), 5)
                @test f ≈ MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1, 4], [x, y]), 5) + MOI.SingleVariable(x)
                @test f ≈ MOI.SingleVariable(x) - MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([-1, -4], [x, y]), -5)
                @test f ≈ MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([3, 4], [x, y]), 5) - MOI.SingleVariable(x)
            end
            @testset "modification" begin
                f = MOIU.modifyfunction(f, MOI.ScalarConstantChange(6))
                @test f.constant == 6
                g = deepcopy(f)
                @test g ≈ f
                f = MOIU.modifyfunction(f, MOI.ScalarCoefficientChange(y, 3))
                @test !(g ≈ f)
                @test g.terms == MOI.ScalarAffineTerm.([2, 4], [x, y])
                @test f.terms == MOI.ScalarAffineTerm.([2, 3], [x, y])
                f = MOIU.modifyfunction(f, MOI.ScalarCoefficientChange(x, 0))
                @test f.terms == MOI.ScalarAffineTerm.([3], [y])
            end
        end
        @testset "Quadratic" begin
            @testset "promote_operation" begin
                @test MOIU.promote_operation(+, Int,
                                             MOI.ScalarQuadraticFunction{Int},
                                             MOI.ScalarQuadraticFunction{Int}) == MOI.ScalarQuadraticFunction{Int}
                @test MOIU.promote_operation(+, Int,
                                             MOI.ScalarQuadraticFunction{Int},
                                             MOI.ScalarAffineFunction{Int}) == MOI.ScalarQuadraticFunction{Int}
                @test MOIU.promote_operation(+, Int,
                                             MOI.ScalarAffineFunction{Int},
                                             MOI.ScalarQuadraticFunction{Int}) == MOI.ScalarQuadraticFunction{Int}
                @test MOIU.promote_operation(*, Int,
                                             MOI.SingleVariable,
                                             MOI.SingleVariable) == MOI.ScalarQuadraticFunction{Int}
                @test MOIU.promote_operation(*, Float64,
                                             MOI.SingleVariable,
                                             MOI.ScalarAffineFunction{Float64}) == MOI.ScalarQuadraticFunction{Float64}
                @test MOIU.promote_operation(*, Int,
                                             MOI.ScalarAffineFunction{Int},
                                             MOI.SingleVariable) == MOI.ScalarQuadraticFunction{Int}
                @test MOIU.promote_operation(*, Float64,
                                             MOI.ScalarAffineFunction{Float64},
                                             MOI.ScalarAffineFunction{Float64}) == MOI.ScalarQuadraticFunction{Float64}
                @test MOIU.promote_operation(/, Float64,
                                             MOI.ScalarQuadraticFunction{Float64},
                                             Float64) == MOI.ScalarQuadraticFunction{Float64}
            end
            fx = MOI.SingleVariable(x)
            fy = MOI.SingleVariable(y)
            f = 7 + 3fx + 1fx * fx + 2fy * fy + 3fx * fy
            MOIU.canonicalize!(f)
            @test MOI.output_dimension(f) == 1
            @testset "isapprox_zero" begin
                @test !MOIU.isapprox_zero(f, 1e-8)
                # Test isapprox_zero with zero terms
                @test MOIU.isapprox_zero(0 * f, 1e-8)
                g = 1.0fx * fy - (1 + 1e-6) * fy * fx
                MOIU.canonicalize!(g)
                @test MOIU.isapprox_zero(g, 1e-5)
                @test !MOIU.isapprox_zero(g, 1e-7)
            end
            @testset "convert" begin
                @test_throws InexactError convert(MOI.SingleVariable, f)
                @test_throws InexactError convert(MOI.ScalarAffineFunction{Int},
                                                  f)
                g = convert(MOI.ScalarQuadraticFunction{Float64}, fx)
                @test convert(MOI.SingleVariable, g) == fx
            end
            @testset "operate" begin
                @test f ≈ 7 + (fx + 2fy) * (1fx + fy) + 3fx
                @test f ≈ 7 + MOIU.operate(*, Int, fx, fx) + 3fx * (fy + 1) + 2fy * fy
                @test f ≈ (fx + 2) * (fx + 1) + (fy + 1) * (2fy + 3fx) + (5 - 3fx - 2fy)
                @test f ≈ begin
                    MOI.ScalarQuadraticFunction([MOI.ScalarAffineTerm(3, x)],
                                                MOI.ScalarQuadraticTerm.([1], [x], [x]), 4) +
                    MOI.ScalarQuadraticFunction(MOI.ScalarAffineTerm{Int}[],
                                            MOI.ScalarQuadraticTerm.([2, 3], [y, x], [y, y]), 3)
                end
                @test f ≈ begin
                    MOI.ScalarQuadraticFunction([MOI.ScalarAffineTerm(3, x)],
                                                MOI.ScalarQuadraticTerm.([1], [x], [x]), 10) -
                    MOI.ScalarQuadraticFunction(MOI.ScalarAffineTerm{Int}[],
                                                MOI.ScalarQuadraticTerm.([-2, -3], [y, x], [y, y]), 3)
                end
                @test f ≈ begin
                    MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(3, x)], 5) +
                    MOI.ScalarQuadraticFunction(MOI.ScalarAffineTerm{Int}[],
                                                MOI.ScalarQuadraticTerm.([1, 2, 3], [x, y, x], [x, y, y]), 2)
                end
                @test f ≈ begin
                    MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(3, x)], 5) -
                    MOI.ScalarQuadraticFunction(MOI.ScalarAffineTerm{Int}[],
                                                MOI.ScalarQuadraticTerm.([-1, -2, -3], [x, y, x], [x, y, y]), -2)
                end
                @test f ≈ begin
                    MOI.ScalarQuadraticFunction(MOI.ScalarAffineTerm{Int}[],
                                                MOI.ScalarQuadraticTerm.([1, 2, 3], [x, y, x], [x, y, y]), 2) +
                    MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(3, x)], 5)
                end
                @test f ≈ begin
                    MOI.ScalarQuadraticFunction(MOI.ScalarAffineTerm{Int}[],
                                                MOI.ScalarQuadraticTerm.([1, 2, 3], [x, y, x], [x, y, y]), 12) -
                    MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(-3, x)], 5)
                end
                @test f ≈ begin
                    MOI.ScalarQuadraticFunction(MOI.ScalarAffineTerm.([2], [x]),
                                                MOI.ScalarQuadraticTerm.([1, 2, 3], [x, y, x], [x, y, y]), 7) +
                    MOI.SingleVariable(x)
                end
                @test f ≈ MOI.ScalarQuadraticFunction(MOI.ScalarAffineTerm.([3], [x]),
                                                      MOI.ScalarQuadraticTerm.([1, 2, 3], [x, y, x], [x, y, y]), 10) - 3
            end
            @testset "modification" begin
                f = MOIU.modifyfunction(f, MOI.ScalarConstantChange(9))
                @test f.constant == 9
                f = MOIU.modifyfunction(f, MOI.ScalarCoefficientChange(y, 0))
                @test f.affine_terms == MOI.ScalarAffineTerm.([3], [x])
                g = deepcopy(f)
                @test f ≈ g
                f = MOIU.modifyfunction(f, MOI.ScalarCoefficientChange(y, 2))
                @test !(f ≈ g)
                @test g.affine_terms == MOI.ScalarAffineTerm.([3], [x])
                @test f.affine_terms == MOI.ScalarAffineTerm.([3, 2], [x, y])
            end
        end
    end
    @testset "Vector" begin
        @testset "Affine" begin
            f = MOIU.canonical(MOI.VectorAffineFunction(MOI.VectorAffineTerm.([2, 1, 2,  1,  1,  2, 2,  2, 2, 1, 1,  2, 1,  2],
                                                                              MOI.ScalarAffineTerm.([3, 2, 3, -3, -1, -2, 3, -2, 1, 3, 5, -2, 0, -1],
                                                                                [x, x, z,  y,  y,  x, y,  z, x, y, y,  x, x,  z])), [5, 7]))
            @test MOI.output_dimension(f) == 2
            @test f.terms == MOI.VectorAffineTerm.([1, 1, 2], MOI.ScalarAffineTerm.([2, 4, 3], [x, y, y]))
            @test MOIU.constant(f) == [5, 7]
            f = MOIU.modifyfunction(f, MOI.VectorConstantChange([6, 8]))
            @test MOIU.constant(f) == [6, 8]
            g = deepcopy(f)
            @test f ≈ g
            f = MOIU.modifyfunction(f, MOI.MultirowChange(y, [(2, 9)]))
            @test !(f ≈ g)
            @test f.terms == MOI.VectorAffineTerm.([1, 1, 2], MOI.ScalarAffineTerm.([2, 4, 9], [x, y, y]))
            @test g.terms == MOI.VectorAffineTerm.([1, 1, 2], MOI.ScalarAffineTerm.([2, 4, 3], [x, y, y]))
            f = MOIU.modifyfunction(f, MOI.MultirowChange(y, [(1, 0)]))
            @test f.terms == MOI.VectorAffineTerm.([1, 2], MOI.ScalarAffineTerm.([2, 9], [x, y]))
        end
        @testset "Quadratic" begin
            f = MOI.VectorQuadraticFunction(MOI.VectorAffineTerm.([1, 2, 2], MOI.ScalarAffineTerm.([3, 1, 2], [x, x, y])), MOI.VectorQuadraticTerm.([1, 1, 2], MOI.ScalarQuadraticTerm.([1, 2, 3], [x, y, x], [x, y, y])), [7, 3, 4])
            @test MOI.output_dimension(f) == 3
            f = MOIU.modifyfunction(f, MOI.VectorConstantChange([10, 11, 12]))
            @test MOIU.constant(f) == [10, 11, 12]
            f = MOIU.modifyfunction(f, MOI.MultirowChange(y, [(2, 0), (1, 1)]))
            @test f.affine_terms == MOI.VectorAffineTerm.([1, 2, 1], MOI.ScalarAffineTerm.([3, 1, 1], [x, x, y]))
            g = deepcopy(f)
            f = MOIU.modifyfunction(f, MOI.MultirowChange(x, [(1, 0), (3, 4)]))
            @test f.affine_terms == MOI.VectorAffineTerm.([2, 1, 3], MOI.ScalarAffineTerm.([1, 1, 4], [x, y, x]))
            @test g.affine_terms == MOI.VectorAffineTerm.([1, 2, 1], MOI.ScalarAffineTerm.([3, 1, 1], [x, x, y]))
        end
    end
    @testset "Conversion to canonical form" begin
        function isapprox_ordered(f1::T, f2::T) where {T <: Union{MOI.ScalarAffineFunction, MOI.VectorAffineFunction}}
            ((MOI.term_indices.(f1.terms) == MOI.term_indices.(f2.terms)) &&
             (MOI._constant(f1) ≈ MOI._constant(f2)) &&
             (MOI.coefficient.(f1.terms) ≈ MOI.coefficient.(f2.terms)))
        end
        function test_canonicalization(f::T, expected::T) where {T <: Union{MOI.ScalarAffineFunction, MOI.VectorAffineFunction}}
            @test MOIU.iscanonical(expected)
            g = @inferred(MOIU.canonical(f))
            @test isapprox_ordered(g, expected)
            @test MOIU.iscanonical(g)
            @test MOIU.iscanonical(expected)
            @test isapprox_ordered(MOIU.canonical(g), g)
            @test MOIU.canonical(g) !== g
            @test @allocated(MOIU.canonicalize!(f)) == 0
        end
        @testset "ScalarAffine" begin
            @test MOIU.iscanonical(MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(Float64[], MOI.VariableIndex.(Int[])), 1.0))
            @test !MOIU.iscanonical(MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([0.0], MOI.VariableIndex.([1])), 1.0))
            @test !MOIU.iscanonical(MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1.0, 2.0], MOI.VariableIndex.([2, 1])), 2.0))
            @test !MOIU.iscanonical(MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1.0, 0.0], MOI.VariableIndex.([1, 2])), 2.0))

            test_canonicalization(
                MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(Float64[], MOI.VariableIndex[]), 1.5),
                MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(Float64[], MOI.VariableIndex[]), 1.5),
                )
            test_canonicalization(
                MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([0.0], [MOI.VariableIndex(1)]), -2.0),
                MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(Float64[], MOI.VariableIndex[]), -2.0),
                )
            test_canonicalization(
                MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([0.0], [MOI.VariableIndex(2)]), -2.0),
                MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(Float64[], MOI.VariableIndex[]), -2.0),
                )
            test_canonicalization(
                MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([3.0], [MOI.VariableIndex(2)]),  1.0),
                MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([3.0], [MOI.VariableIndex(2)]),  1.0),
                )
            test_canonicalization(
                MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([3.0, 4.0], MOI.VariableIndex.([2, 1])), 0.0),
                MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([4.0, 3.0], MOI.VariableIndex.([1, 2])), 0.0),
                )
            test_canonicalization(
                MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1.0, 0.1], MOI.VariableIndex.([1, 1])), 5.0),
                MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1.1], MOI.VariableIndex.([1])), 5.0),
                )
            test_canonicalization(
                MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1.0, 0.5, 2.0], MOI.VariableIndex.([1, 3, 1])), 5.0),
                MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([3.0, 0.5], MOI.VariableIndex.([1, 3])), 5.0),
                )
            test_canonicalization(
                MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1.0, 0.5, 2.0], MOI.VariableIndex.([1, 3, 1])), 5.0),
                MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([3.0, 0.5], MOI.VariableIndex.([1, 3])), 5.0),
                )
            test_canonicalization(
                MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1.0, 2.0, 3.0, 4.0, 5.0], MOI.VariableIndex.([1, 3, 1, 3, 2])), 5.0),
                MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([4.0, 5.0, 6.0], MOI.VariableIndex.([1, 2, 3])), 5.0),
                )
            test_canonicalization(
                MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1.0, -1.0], MOI.VariableIndex.([7, 7])), 5.0),
                MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(Float64[], MOI.VariableIndex.(Int[])), 5.0),
                )
            test_canonicalization(
                MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1.0, -1.0, 0.5], MOI.VariableIndex.([7, 7, 2])), 5.0),
                MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([0.5], MOI.VariableIndex.([2])), 5.0),
                )
            test_canonicalization(
                MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1.0, -0.5, 0.5, -0.5], MOI.VariableIndex.([7, 7, 2, 7])), 5.0),
                MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([0.5], MOI.VariableIndex.([2])), 5.0),
                )
        end
        @testset "VectorAffine" begin
            @test MOIU.iscanonical(MOI.VectorAffineFunction(MOI.VectorAffineTerm.(Int[], MOI.ScalarAffineTerm.(Float64[], MOI.VariableIndex.(Int[]))), Float64[]))
            @test !MOIU.iscanonical(MOI.VectorAffineFunction(MOI.VectorAffineTerm.([1], MOI.ScalarAffineTerm.([0.0], MOI.VariableIndex.([1]))), [1.0]))
            @test !MOIU.iscanonical(MOI.VectorAffineFunction(MOI.VectorAffineTerm.([1, 2], MOI.ScalarAffineTerm.([0.0, 1.0], MOI.VariableIndex.([1, 2]))), [1.0]))
            @test !MOIU.iscanonical(MOI.VectorAffineFunction(MOI.VectorAffineTerm.([2, 1], MOI.ScalarAffineTerm.([1.0, 1.0], MOI.VariableIndex.([1, 2]))), [1.0]))
            @test !MOIU.iscanonical(MOI.VectorAffineFunction(MOI.VectorAffineTerm.([1, 1], MOI.ScalarAffineTerm.([1.0, -1.0], MOI.VariableIndex.([1, 1]))), [1.0]))
            @test !MOIU.iscanonical(MOI.VectorAffineFunction(MOI.VectorAffineTerm.([1, 1], MOI.ScalarAffineTerm.([1.0, 1.0], MOI.VariableIndex.([1, 1]))), [1.0]))

            test_canonicalization(
                MOI.VectorAffineFunction(MOI.VectorAffineTerm.(Int[], MOI.ScalarAffineTerm.(Float64[], MOI.VariableIndex.(Int[]))), Float64[]),
                MOI.VectorAffineFunction(MOI.VectorAffineTerm.(Int[], MOI.ScalarAffineTerm.(Float64[], MOI.VariableIndex.(Int[]))), Float64[])
                )
            test_canonicalization(
                MOI.VectorAffineFunction(MOI.VectorAffineTerm.([3], MOI.ScalarAffineTerm.([0.0], MOI.VariableIndex.([5]))), [1.0]),
                MOI.VectorAffineFunction(MOI.VectorAffineTerm.(Int[], MOI.ScalarAffineTerm.(Float64[], MOI.VariableIndex.(Int[]))), [1.0])
                )
            test_canonicalization(
                MOI.VectorAffineFunction(MOI.VectorAffineTerm.([3, 2], MOI.ScalarAffineTerm.([1.0, 2.0], MOI.VariableIndex.([5, 6]))), [1.0, 2.0, 3.0]),
                MOI.VectorAffineFunction(MOI.VectorAffineTerm.([2, 3], MOI.ScalarAffineTerm.([2.0, 1.0], MOI.VariableIndex.([6, 5]))), [1.0, 2.0, 3.0])
                )
            test_canonicalization(
                MOI.VectorAffineFunction(MOI.VectorAffineTerm.([3, 3], MOI.ScalarAffineTerm.([1.0, 2.0], MOI.VariableIndex.([6, 5]))), [1.0, 2.0, 3.0]),
                MOI.VectorAffineFunction(MOI.VectorAffineTerm.([3, 3], MOI.ScalarAffineTerm.([2.0, 1.0], MOI.VariableIndex.([5, 6]))), [1.0, 2.0, 3.0])
                )
            test_canonicalization(
                MOI.VectorAffineFunction(MOI.VectorAffineTerm.([3, 3], MOI.ScalarAffineTerm.([1.0, 2.0], MOI.VariableIndex.([1, 1]))), [1.0, 2.0, 3.0]),
                MOI.VectorAffineFunction(MOI.VectorAffineTerm.([3], MOI.ScalarAffineTerm.([3.0], MOI.VariableIndex.([1]))), [1.0, 2.0, 3.0])
                )
            test_canonicalization(
                MOI.VectorAffineFunction(MOI.VectorAffineTerm.([1, 1, 1], MOI.ScalarAffineTerm.([1.0, 2.0, 3.0], MOI.VariableIndex.([1, 2, 1]))), [4.0, 5.0, 6.0]),
                MOI.VectorAffineFunction(MOI.VectorAffineTerm.([1, 1], MOI.ScalarAffineTerm.([4.0, 2.0], MOI.VariableIndex.([1, 2]))), [4.0, 5.0, 6.0]),
                )
            test_canonicalization(
                MOI.VectorAffineFunction(MOI.VectorAffineTerm.([1, 1, 1], MOI.ScalarAffineTerm.([1.0, 2.0, 3.0], MOI.VariableIndex.([2, 1, 1]))), [4.0, 5.0, 6.0]),
                MOI.VectorAffineFunction(MOI.VectorAffineTerm.([1, 1], MOI.ScalarAffineTerm.([5.0, 1.0], MOI.VariableIndex.([1, 2]))), [4.0, 5.0, 6.0]),
                )
            test_canonicalization(
                MOI.VectorAffineFunction(MOI.VectorAffineTerm.([2, 3, 3], MOI.ScalarAffineTerm.([1.0, 2.0, 3.0], MOI.VariableIndex.([1, 1, 1]))), [4.0, 5.0, 6.0]),
                MOI.VectorAffineFunction(MOI.VectorAffineTerm.([2, 3], MOI.ScalarAffineTerm.([1.0, 5.0], MOI.VariableIndex.([1, 1]))), [4.0, 5.0, 6.0]),
                )
            test_canonicalization(
                MOI.VectorAffineFunction(MOI.VectorAffineTerm.([2, 3, 3], MOI.ScalarAffineTerm.([1.0, -3.0, 3.0], MOI.VariableIndex.([1, 1, 1]))), [4.0, 5.0, 6.0]),
                MOI.VectorAffineFunction(MOI.VectorAffineTerm.([2], MOI.ScalarAffineTerm.([1.0], MOI.VariableIndex.([1]))), [4.0, 5.0, 6.0]),
                )
            test_canonicalization(
                MOI.VectorAffineFunction(MOI.VectorAffineTerm.([2, 3, 3, 3], MOI.ScalarAffineTerm.([1.0, 3.0, -1.0, -2.0], MOI.VariableIndex.([1, 1, 1, 1]))), [4.0, 5.0, 6.0]),
                MOI.VectorAffineFunction(MOI.VectorAffineTerm.([2], MOI.ScalarAffineTerm.([1.0], MOI.VariableIndex.([1]))), [4.0, 5.0, 6.0]),
                )
        end
    end
end


text:
rabit_finalize() = ccall((:RabitFinalize, _jl_libxgboost), Nothing, ())
function rabit_init()
    argv = Ref{Ptr{Nothing}}()
    ccall((:RabitInit, _jl_libxgboost), Nothing, (Cint, Ref{Ptr{Nothing}}), 0, argv)
end

function rabit_is_distributed()
    ret = ccall((:RabitIsDistributed, _jl_libxgboost), Cint, ())
    return (ret != Cint(0))
end

rabit_get_rank() = ccall((:RabitGetRank, _jl_libxgboost), Cint, ())

rabit_get_world_size() = ccall((:RabitGetWorldSize, _jl_libxgboost), Cint, ())

rabit_get_version_number() = ccall((:RabitVersionNumber, _jl_libxgboost), Cint, ())

ext: jl


text:
import Dates
import Pkg
import Tar

function get_bool_from_env(name::AbstractString, default_value::Bool)
    value = get(ENV, name, "$(default_value)") |> strip |> lowercase
    result = parse(Bool, value)::Bool
    return result
end

const is_buildkite         = get_bool_from_env("BUILDKITE",                  false)
const always_save_rr_trace = get_bool_from_env("JULIA_ALWAYS_SAVE_RR_TRACE", false)

function get_from_env(name::AbstractString)
    if is_buildkite
        value = ENV[name]
    else
        value = get(ENV, name, "")
    end
    result = convert(String, strip(value))::String
    return result
end

function my_exit(process::Base.Process)
    wait(process)

    @info(
        "",
        process.exitcode,
        process.termsignal,
    )

    # Pass the exit code back up
    if process.termsignal != 0
        ccall(:raise, Cvoid, (Cint,), process.termsignal)

        # If for some reason the signal did not cause an exit, we'll exit manually.
        # We need to make sure that we exit with a non-zero exit code.
        if process.exitcode != 0
            exit(process.exitcode)
        else
            exit(1)
        end
    end
    exit(process.exitcode)
end

if Base.VERSION < v"1.6"
    throw(ErrorException("The `$(basename(@__FILE__))` script requires Julia 1.6 or greater"))
end

if length(ARGS) < 1
    throw(ErrorException("Usage: julia $(basename(@__FILE__)) [command...]"))
end

@info "We will run the command under rr"

const build_number                      = get_from_env("BUILDKITE_BUILD_NUMBER")
const job_name                          = get_from_env("BUILDKITE_STEP_KEY")
const commit_full                       = get_from_env("BUILDKITE_COMMIT")
const commit_short                      = first(commit_full, 10)
const JULIA_TEST_RR_TIMEOUT             = get(ENV,  "JULIA_TEST_RR_TIMEOUT", "120")
const timeout_minutes                   = parse(Int, JULIA_TEST_RR_TIMEOUT)
const JULIA_TEST_NUM_CORES              = get(ENV,  "JULIA_TEST_NUM_CORES", "8")
const julia_test_num_cores_int          = parse(Int, JULIA_TEST_NUM_CORES)
const num_cores = min(
    8,
    Sys.CPU_THREADS,
    julia_test_num_cores_int + 1,
)

ENV["JULIA_RRCAPTURE_NUM_CORES"] = "$(num_cores)"

@info(
    "",
    build_number,
    job_name,
    commit_full,
    commit_short,
    timeout_minutes,
    num_cores,
)

const dumps_dir       = joinpath(pwd(), "dumps")
const temp_parent_dir = joinpath(pwd(), "temp_for_rr")

mkpath(dumps_dir)
mkpath(temp_parent_dir)

proc = nothing

mktempdir(temp_parent_dir) do dir
    Pkg.activate(dir)
    Pkg.add("rr_jll")
    Pkg.add("Zstd_jll")

    rr_jll = Base.require(Base.PkgId(Base.UUID((0xe86bdf43_55f7_5ea2_9fd0_e7daa2c0f2b4)), "rr_jll"))
    zstd_jll = Base.require(Base.PkgId(Base.UUID((0x3161d3a3_bdf6_5164_811a_617609db77b4)), "Zstd_jll"))
    rr(func) = Base.invokelatest(rr_jll.rr, func; adjust_LIBPATH=false)
    rr() do rr_path
        capture_script_path = joinpath(dir, "capture_output.sh")
        loader = Sys.WORD_SIZE == 64 ? "/lib64/ld-linux-x86-64.so.2" : "/lib/ld-linux.so.2"
        open(capture_script_path, "w") do io
            write(io, """
            #!/bin/bash

            $(rr_path) record --nested=detach "\$@" > >(tee -a $(dir)/stdout.log) 2> >(tee -a $(dir)/stderr.log >&2)
            """)
        end
        chmod(capture_script_path, 0o755)

        new_env = copy(ENV)
        new_env["_RR_TRACE_DIR"] = joinpath(dir, "rr_traces")
        new_env["RR_LOG"]="all:debug"
        new_env["RR_LOG_BUFFER"]="100000"
        new_env["JULIA_RR"] = capture_script_path
        t_start = time()
        global proc = run(setenv(`$(rr_path) record --num-cores=$(num_cores) $ARGS`, new_env), (stdin, stdout, stderr); wait=false)

        # Start asynchronous timer that will kill `rr`
        @async begin
            sleep(timeout_minutes * 60)

            # If we've exceeded the timeout and `rr` is still running, kill it.
            if isopen(proc)
                println(stderr, "\n\nProcess timed out (with a timeout of $(timeout_minutes) minutes). Signalling `rr` for force-cleanup!")
                kill(proc, Base.SIGTERM)

                # Give `rr` a chance to cleanup and upload.
                # Note: this time period includes the time to upload the `rr` trace files
                # as Buildkite artifacts, so make sure it is long enough to allow the
                # uploads to finish.
                cleanup_minutes = 30
                sleep(cleanup_minutes * 60)

                if isopen(proc)
                    println(stderr, "\n\n`rr` failed to cleanup and upload within $(cleanup_minutes) minutes, killing and exiting immediately!")
                    kill(proc, Base.SIGKILL)
                    exit(1)
                end
            end
        end

        # Wait for `rr` to finish, either through naturally finishing its run, or `SIGTERM`.
        wait(proc)
        process_failed = !success(proc)

        if process_failed || always_save_rr_trace || is_buildkite
            println(stderr, "`rr` returned $(proc.exitcode), packing and uploading traces...")

            if !isdir(joinpath(dir, "rr_traces"))
                println(stderr, "No `rr_traces` directory!  Did `rr` itself fail?")
                exit(1)
            end

            # Clean up non-traces
            rm(joinpath(dir, "rr_traces", "latest-trace"))
            rm(joinpath(dir, "rr_traces", "cpu_lock"))

            # Create a directory for the pack files to go
            pack_dir = joinpath(dir, "pack")
            mkdir(pack_dir)

            # Pack all traces
            trace_dirs = [joinpath(dir, "rr_traces", f) for f in readdir(joinpath(dir, "rr_traces"))]
            filter!(isdir, trace_dirs)
            run(ignorestatus(`$(rr_path) pack --pack-dir=$pack_dir $(trace_dirs)`))

            # Tar it up
            mkpath(dumps_dir)
            date_str = Dates.format(Dates.now(), Dates.dateformat"yyyy_mm_dd_HH_MM_SS")
            dst_file_name = string(
                "rr",
                "--build_$(build_number)",
                "--$(job_name)",
                "--commit_$(commit_short)",
                "--$(date_str)",
                ".tar.zst",
            )
            dst_full_path = joinpath(dumps_dir, dst_file_name)
            zstd_jll.zstdmt() do zstdp
                tarproc = open(`$(zstdp) -o $(dst_full_path)`, "w")
                Tar.create(dir, tarproc)
                close(tarproc.in)
            end

            @info "The `rr` trace file has been saved to: $(dst_full_path)"
            if is_buildkite
                @info "Since this is a Buildkite run, we will upload the `rr` trace file."
                cd(dumps_dir) do
                    run(`buildkite-agent artifact upload $(dst_file_name)`)
                end
            end
        end

    end
end

@info "Finished running the command under rr"
my_exit(proc)

max_stars_repo_name: wentasah/julia

max_issues_repo_name: wentasah/julia

max_forks_repo_name: wentasah/julia


text:
using Cliffords, Base.Test
using Compat

import Cliffords: IZ, ZI, XI, IX, YI, IY, II, XX, YY, ZZ, XY, XZ, YX, ZX,
	generators

# Paulis
@test X * Id == X
@test Id * X == X
@test Y * Id == Y
@test Z * Id == Z

@test X * X == Id
@test Y * Y == Id
@test Z * Z == Id

@test X * Y == im*Z
@test Y * Z == im*X
@test Z * X == im*Y
@test Y * X == -im*Z

@test Id < X
@test X < Y
@test Y < Z

@test II < IX
@test IX < XX
@test XI < XX
@test IX < IY
@test XI < YI
@test XX < YY
@test XX < XY
@test YX > XX

# generators
@test generators(X) == [X]
@test generators(Z) == [Z]
@test generators(Y) == [im*X, Z]

@test generators(XX) == [XI, IX]
@test generators(ZZ) == [ZI, IZ]
@test generators(XY) == [im*XI, IX, IZ]
@test generators(YX) == [im*XI, ZI, IX]
@test generators(YY) == [-XI, ZI, IX, IZ]

XII = kron(X,Id,Id)
IXI = kron(Id,X,Id)
IIX = kron(Id,Id,X)
ZII = kron(Z,Id,Id)
IZI = kron(Id,Z,Id)
IIZ = kron(Id,Id,Z)

@test generators(kron(X,X,X)) == [XII, IXI, IIX]
@test generators(kron(Z,Z,Z)) == [ZII, IZI, IIZ]
@test generators(kron(X,Y,Z)) == [im*XII, IXI, IZI, IIZ]

@test Pauli([1 0; 0 1]) == Id
@test Pauli([0 1; 1 0]) == X
@test Pauli([0 -im; im 0]) == Y
@test Pauli([1 0; 0 -1]) == Z

@test complex(paulieye(2)) == eye(4)

# Cliffords

@test Clifford(1/sqrt(2) * [1 1; 1 -1]) == H
@test Clifford(eye(2)) == RI
@test Clifford(eye(4)) == kron(RI,RI)
@test Clifford([1 0 0 0; 0 1 0 0; 0 0 0 1; 0 0 1 0]) == CNOT
@test Clifford(diagm([1,1,1,-1])) == CZ
@test Clifford(expm(-im*pi/4*[1 0; 0 -1])) == S

function eq_upto_phase(A, B)
	idx = findfirst(A)
	rel_phase = (B[idx] == 0) ? 1.0 : (A[idx] / B[idx])
	return rel_phase * A ≈ B
end
@test eq_upto_phase(complex(RI), eye(2))
@test eq_upto_phase(complex(H), 1/sqrt(2) * [1 1; 1 -1])
@test eq_upto_phase(complex(CNOT), [1 0 0 0; 0 1 0 0; 0 0 0 1; 0 0 1 0])

# Cliffords * Paulis
@test H * Id == Id
@test H * X == Z
@test H * Z == X
@test H * Y == -Y

II = kron(Id,Id)

@test kron(RI, H) * II == II
@test kron(RI, H) * IX == IZ
@test kron(RI, H) * IZ == IX
@test kron(RI, H) * IY == -IY

@test CNOT * II == II
@test CNOT * IX == IX
@test CNOT * XI == XX
@test CNOT * YY == -XZ

# Cliffords \ Paulis
@test H \ Id == Id
@test H \ X == Z
@test H \ Z == X
@test H \ Y == -Y

II = kron(Id,Id)

@test kron(RI, H) \ II == II
@test kron(RI, H) \ IX == IZ
@test kron(RI, H) \ IZ == IX
@test kron(RI, H) \ IY == -IY

@test CNOT \ II == II
@test CNOT \ IX == IX
@test CNOT \ XI == XX
@test CNOT \ YY == -XZ

# Cliffords * Cliffords

@test H * S * H == Clifford(@compat(Dict(+X=>+X,+Z=>-Y)),@compat Dict(+X=>+X,+Z=>+Y))
@test H * S * H == Clifford(expm(-im*pi/4*[0 1; 1 0]))
@test RY * RX * RY == SelfInverseClifford(@compat Dict(+X=>+X,+Z=>-Z))
@test kron(RI, H) * CNOT * kron(RI, H) == SelfInverseClifford(@compat Dict(+IZ=>+IZ,+ZI=>+ZI,+XI=>+XZ,+IX=>+ZX))
@test kron(RI, H) * CNOT * kron(RI, H) == CZ
@test S * S == RZ

# 3 CNOTs is a SWAP
CNOT21 = expand(CNOT, [2,1], 2)
@test CNOT * CNOT21 * CNOT == SWAP

# iSWAP
iSWAP = CZ*kron(S,S)*SWAP
@test iSWAP == Clifford([1 0 0 0; 0 0 im 0; 0 im 0 0; 0 0 0 1])

# Cliffords \ Cliffords
@test H \ H == H * H
@test CNOT \ CNOT == CNOT * CNOT
@test RY * RX * RY == RY \ (RX * RY)
@test S \ S == RI
@test S \ RZ == S

# Local Cliffords
@test localclifford(1) == RI

# Weight
for i=1:20
  v = rand(10)
  vX = (v .> .25) .* (v .< .5)
  vY = 2*(v .> .5) .* (v .< .75)
  vZ = 3*(v .> .75)
  r = rand()
  rS = (r > .25) + (r > .5) + (r > .75)
  @test weight(Pauli(vX + vY + vZ,rS)) == sum(v .> .25)
end

#
@test_approx_eq norm(complex(X)-[0 1; 1 0]) 0
@test_approx_eq norm(complex(Y)-[0 -1im;1im 0]) 0
@test_approx_eq norm(complex(Z)-[1 0; 0 -1]) 0


text:
immutable TProblem{T<:Integer,U<:String}
    sd::Array{Array{T,1},1}
    toc::Array{T,2}
    labels::Array{Array{U,1},1}
    tsort::Array{Array{T,2}, 1}
end

function TProblem{T<:Integer,U<:String}(s::Array{T,1},
                                        d::Array{T,1},
                                        toc::Array{T,2},
                                        slab::Array{U,1},
                                        dlab::Array{U,1})
    scnt = length(s)
    dcnt = length(d)
    size(toc) = (scnt,dcnt) || error("Supply, Demand, TOC Size Mismatch")
    length(slab) == scnt || error("Supply Label Size Labels")
    length(dlab) == dcnt || error("Demand Label Size Labels")
    0 <= minimum(s) || error("Negative Supply Value")
    0 <= minimum(d) || error("Negative Demand Value")
    sd = Array{T,1}[]
    push!(sd, s)
    push!(sd, d)
    labels = Array{U,1}[]
    push!(labels, slab)
    push!(labels, dlab)
    tsort = Array{T,2}[]
    push!(tsort, mapslices(sortperm, toc, 2))
    push!(tsort, mapslices(sortperm, toc, 1))
    TProblem(sd, toc, labels, tsort)
end
isbalanced(tp::TProblem) = sum(tp.sd[1]) == sum(tp.sd[2])

type Resource{T<:Integer}
    dim::T
    i::T
    quant::T
    l::T
    m::T
    p::T
    q::T
end
function Resource{T<:Integer}(dim::T, i::T, quant::T)
    zed = zero(T)
    Resource(dim, i, quant, zed, zed, zed, zed)
end

isavailable(r::Resource) = 0 < r.quant
Base.isless(a::Resource, b::Resource) = a.p < b.p || (a.p == b.p && b.q < a.q)

max_stars_repo_name: ethansaxenian/RosettaDecode

max_issues_repo_name: ethansaxenian/RosettaDecode

max_forks_repo_name: ethansaxenian/RosettaDecode