|  | 
|  | 1 | +function SciMLBase.LinearProblem(sys::System, op; kwargs...) | 
|  | 2 | +    SciMLBase.LinearProblem{true}(sys, op; kwargs...) | 
|  | 3 | +end | 
|  | 4 | + | 
|  | 5 | +function SciMLBase.LinearProblem(sys::System, op::StaticArray; kwargs...) | 
|  | 6 | +    SciMLBase.LinearProblem{false}(sys, op; kwargs...) | 
|  | 7 | +end | 
|  | 8 | + | 
|  | 9 | +function SciMLBase.LinearProblem{iip}( | 
|  | 10 | +        sys::System, op; check_length = true, expression = Val{false}, | 
|  | 11 | +        check_compatibility = true, sparse = false, eval_expression = false, | 
|  | 12 | +        eval_module = @__MODULE__, checkbounds = false, cse = true, | 
|  | 13 | +        u0_constructor = identity, u0_eltype = nothing, kwargs...) where {iip} | 
|  | 14 | +    check_complete(sys, LinearProblem) | 
|  | 15 | +    check_compatibility && check_compatible_system(LinearProblem, sys) | 
|  | 16 | + | 
|  | 17 | +    _, u0, p = process_SciMLProblem( | 
|  | 18 | +        EmptySciMLFunction{iip}, sys, op; check_length, expression, | 
|  | 19 | +        build_initializeprob = false, symbolic_u0 = true, u0_constructor, u0_eltype, | 
|  | 20 | +        kwargs...) | 
|  | 21 | + | 
|  | 22 | +    if any(x -> symbolic_type(x) != NotSymbolic(), u0) | 
|  | 23 | +        u0 = nothing | 
|  | 24 | +    end | 
|  | 25 | + | 
|  | 26 | +    u0Type = typeof(op) | 
|  | 27 | +    floatT = if u0 === nothing | 
|  | 28 | +        calculate_float_type(op, u0Type) | 
|  | 29 | +    else | 
|  | 30 | +        eltype(u0) | 
|  | 31 | +    end | 
|  | 32 | +    u0_eltype = something(u0_eltype, floatT) | 
|  | 33 | + | 
|  | 34 | +    u0_constructor = get_p_constructor(u0_constructor, u0Type, u0_eltype) | 
|  | 35 | + | 
|  | 36 | +    A, b = calculate_A_b(sys; sparse) | 
|  | 37 | +    update_A = generate_update_A(sys, A; expression, wrap_gfw = Val{true}, eval_expression, | 
|  | 38 | +        eval_module, checkbounds, cse, kwargs...) | 
|  | 39 | +    update_b = generate_update_b(sys, b; expression, wrap_gfw = Val{true}, eval_expression, | 
|  | 40 | +        eval_module, checkbounds, cse, kwargs...) | 
|  | 41 | +    observedfun = ObservedFunctionCache( | 
|  | 42 | +        sys; steady_state = false, expression, eval_expression, eval_module, checkbounds, | 
|  | 43 | +        cse) | 
|  | 44 | + | 
|  | 45 | +    if expression == Val{true} | 
|  | 46 | +        symbolic_interface = quote | 
|  | 47 | +            update_A = $update_A | 
|  | 48 | +            update_b = $update_b | 
|  | 49 | +            sys = $sys | 
|  | 50 | +            observedfun = $observedfun | 
|  | 51 | +            $(SciMLBase.SymbolicLinearInterface)( | 
|  | 52 | +                update_A, update_b, sys, observedfun, nothing) | 
|  | 53 | +        end | 
|  | 54 | +        get_A = build_explicit_observed_function( | 
|  | 55 | +            sys, A; param_only = true, eval_expression, eval_module) | 
|  | 56 | +        if sparse | 
|  | 57 | +            get_A = SparseArrays.sparse ∘ get_A | 
|  | 58 | +        end | 
|  | 59 | +        get_b = build_explicit_observed_function( | 
|  | 60 | +            sys, b; param_only = true, eval_expression, eval_module) | 
|  | 61 | +        A = u0_constructor(get_A(p)) | 
|  | 62 | +        b = u0_constructor(get_b(p)) | 
|  | 63 | +    else | 
|  | 64 | +        symbolic_interface = SciMLBase.SymbolicLinearInterface( | 
|  | 65 | +            update_A, update_b, sys, observedfun, nothing) | 
|  | 66 | +        A = u0_constructor(update_A(p)) | 
|  | 67 | +        b = u0_constructor(update_b(p)) | 
|  | 68 | +    end | 
|  | 69 | + | 
|  | 70 | +    kwargs = (; u0, process_kwargs(sys; kwargs...)..., f = symbolic_interface) | 
|  | 71 | +    args = (; A, b, p) | 
|  | 72 | + | 
|  | 73 | +    return maybe_codegen_scimlproblem(expression, LinearProblem{iip}, args; kwargs...) | 
|  | 74 | +end | 
|  | 75 | + | 
|  | 76 | +# For remake | 
|  | 77 | +function SciMLBase.get_new_A_b( | 
|  | 78 | +        sys::AbstractSystem, f::SciMLBase.SymbolicLinearInterface, p, A, b; kw...) | 
|  | 79 | +    if ArrayInterface.ismutable(A) | 
|  | 80 | +        f.update_A!(A, p) | 
|  | 81 | +        f.update_b!(b, p) | 
|  | 82 | +    else | 
|  | 83 | +        # The generated function has both IIP and OOP variants | 
|  | 84 | +        A = StaticArraysCore.similar_type(A)(f.update_A!(p)) | 
|  | 85 | +        b = StaticArraysCore.similar_type(b)(f.update_b!(p)) | 
|  | 86 | +    end | 
|  | 87 | +    return A, b | 
|  | 88 | +end | 
|  | 89 | + | 
|  | 90 | +function check_compatible_system(T::Type{LinearProblem}, sys::System) | 
|  | 91 | +    check_time_independent(sys, T) | 
|  | 92 | +    check_affine(sys, T) | 
|  | 93 | +    check_not_dde(sys) | 
|  | 94 | +    check_no_cost(sys, T) | 
|  | 95 | +    check_no_constraints(sys, T) | 
|  | 96 | +    check_no_jumps(sys, T) | 
|  | 97 | +    check_no_noise(sys, T) | 
|  | 98 | +end | 
0 commit comments