Skip to content

Conversation

@ChrisRackauckas-Claude
Copy link

Summary

This PR fixes issue #554 where creating an ODEProblem from a Basis with controls would throw a MethodError because SciMLBase incorrectly detected the basis as supporting in-place evaluation.

Problem

When a Basis{false, true} (no implicit variables, with controls) was passed to ODEProblem, SciMLBase's isinplace check would return true, causing it to call the basis with a 4-argument signature (du, u, p, t). However, Basis{false, CTRLS} only supports out-of-place signatures like (u, p, t) or (u, p, t, c).

The IMPL type parameter determines whether a basis supports in-place evaluation:

  • IMPL=false: Out-of-place only (returns result)
  • IMPL=true: In-place (mutates first argument du)

Solution

Added DiffEqBase.isinplace method for Basis types:

DiffEqBase.isinplace(::Basis{IMPL, CTRLS}, n) where {IMPL, CTRLS} = IMPL

This ensures isinplace correctly returns false for Basis{false, CTRLS} and true for Basis{true, CTRLS}, based solely on whether the basis has implicit variables.

Testing

  • All existing tests pass (252 tests)
  • Verified that isinplace now returns correct value for both Basis{false, false} and Basis{false, true}
  • Confirmed ODEProblem can now be created from Basis without the MethodError

Fixes #554

🤖 Generated with Claude Code

Co-Authored-By: Claude [email protected]

Implement `DiffEqBase.isinplace` for `Basis` to correctly report whether
the basis supports in-place evaluation based on the `IMPL` type parameter.

The issue was that when creating an `ODEProblem` from a `Basis` with
controls but without implicit variables (Basis{false, true}), SciMLBase
would incorrectly detect it as in-place compatible. This caused a
MethodError because:

- Basis{false, CTRLS} only supports out-of-place signatures: (u, p, t) or (u, p, t, c)
- Basis{true, CTRLS} supports in-place signatures: (du, u, p, t) or (du, u, p, t, c)

The fix adds:
```julia
DiffEqBase.isinplace(::Basis{IMPL, CTRLS}, n) where {IMPL, CTRLS} = IMPL
```

This ensures that `isinplace` returns `true` only when the basis has
implicit variables (IMPL=true) and supports in-place evaluation,
and `false` otherwise.

Fixes SciML#554

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@ChrisRackauckas-Claude
Copy link
Author

Investigation Summary

Root Cause Analysis

The error occurred because there was no SciMLBase.isinplace method defined for Basis. When SciMLBase tried to determine if a function supports in-place calls, it likely used a heuristic that detected the 4-argument signature (u, p, t, c) on Basis{false, true} and incorrectly concluded it was an in-place function.

However, the actual signatures are:

  • Basis{false, false}: Out-of-place with no controls: (u, p, t)
  • Basis{false, true}: Out-of-place with controls: (u, p, t, c) ← This was being mistaken for in-place!
  • Basis{true, false}: In-place with no controls: (du, u, p, t)
  • Basis{true, true}: In-place with controls: (du, u, p, t, c)

The IMPL type parameter is what determines in-place vs out-of-place, not the number of arguments.

Implementation Details

The fix is minimal and elegant - just one line:

DiffEqBase.isinplace(::Basis{IMPL, CTRLS}, n) where {IMPL, CTRLS} = IMPL

This leverages the existing type parameter to provide the correct answer without any runtime checks.

Testing Verification

Ran the full test suite (Pkg.test("DataDrivenDiffEq")) - all 252 tests pass with the fix in place.

@ChrisRackauckas ChrisRackauckas merged commit 7613da5 into SciML:master Oct 1, 2025
15 of 19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

solve throws error with ODEProblem created from Basis

2 participants