Skip to content
This repository was archived by the owner on Dec 23, 2025. It is now read-only.

Add support for multidimensional IDEs - #35

Merged
JoshKarpel merged 5 commits into
JoshKarpel:masterfrom
nbrucy:master
Nov 19, 2020
Merged

JoshKarpel merged 5 commits into
JoshKarpel:masterfrom
nbrucy:master

Conversation

@nbrucy

@nbrucy nbrucy commented Nov 17, 2020 •

Copy link
Copy Markdown
Contributor

This PR resolves #28 by adding support to multidimensional IDE.

  • It changes some calls to the numpy and scipy librairies
  • It adds a new test:
    image
    of which the analytical solution is (sin(x), cos(x))

It passes all the tests except one : test_raise_exception_if_unexpectedly_complex.
I don't know how bad it is since it is expected to fail but maybe some extra checks are needed.

@nbrucy nbrucy mentioned this pull request Nov 17, 2020
@nbrucy
nbrucy marked this pull request as draft November 17, 2020 16:53
@JoshKarpel
JoshKarpel self-requested a review November 18, 2020 00:33

@JoshKarpel JoshKarpel left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is awesome! Thank you so much for looking into this. Looks like the changes weren't too painful.

re: the unexpectedly-complex-valued-IDE check, I suspect that what's happening is that, because the inputs are now arrays, numpy is throwing an actual exception instead of a warning: TypeError: can't convert complex to float (buried in the middle of the failing step of https://github.com/JoshKarpel/idesolver/pull/35/checks?check_run_id=1413226346). I think you can make it behave by changing the except np.ComplexWarning block to

            except (np.ComplexWarning, TypeError) as e:
                raise exceptions.UnexpectedlyComplexValuedIDE(
                    "Detected complex-valued IDE. Make sure to pass y_0 as a complex number."
                ) from e

Comment thread idesolver/idesolver.py Outdated
Comment on lines +307 to +309
if self.store_intermediate:
for j in range(len(self.y_intermediate)):
self.y_intermediate[j] = self.y_intermediate[0]

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not obvious to me that this is right - seems like it should be something like self.y_intermediate = [y[0] for y in self.y_intermediate]. Could you add a new test that asserts that the structure of y_intermediate ends up being correct (a list of numbers if ndim == 1, else a list of numpy arrays, I think).

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we can also use zeros_like in other places, we might be able to avoid storing self.ndim at all.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was false indeed, I forgot the index j:
self.y_intermediate[j] = self.y_intermediate[j][0]

But your solution is more Pythonic.

Comment thread tests/test_solver_against_analytic_solutions.py Outdated
Comment thread idesolver/idesolver.py
Comment on lines -375 to +391
y0=np.array([self.y_0]),
y0=self.y_0,

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In hindsight, this makes it rather obvious that it wasn't too far away from working!

Comment thread idesolver/idesolver.py Outdated
Comment thread idesolver/idesolver.py Outdated
ndmin=1,
copy=False)

result = np.zeros(self.ndim, dtype=type(y))

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another potential zeros_like

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually zeros_like here make the tests fail, I think when self.y_0 is an integer.
We can have result = np.zeros_like(self.y_0, dtype=type(y)) instead.

Comment thread idesolver/idesolver.py Outdated
k = lambda x, s: 1
if f is None:
f = lambda y: 0
f = lambda y: np.zeros(self.ndim)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe np.zeros_like(self.y_0)?

Comment thread idesolver/idesolver.py Outdated

if c is None:
c = lambda x, y: 0
c = lambda x, y: np.zeros(self.ndim)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe np.zeros_like(self.y_0)?

Noe Brucy and others added 2 commits November 18, 2020 13:42
 - Improve style
 - Array coercion for all the input functions
 - Catch error for complex valued functions when y_0 is real,
 - Correct conversion of y_intermediate for the scalar case
 - Add test for the shape of y_intermediate
@JoshKarpel JoshKarpel changed the title Add support for multidimensional IDE (#28) Add support for multidimensional IDE Nov 18, 2020
@JoshKarpel JoshKarpel changed the title Add support for multidimensional IDE Add support for multidimensional IDEs Nov 18, 2020
@codecov

codecov Bot commented Nov 18, 2020 •

Copy link
Copy Markdown

Codecov Report

Merging #35 (980c3ae) into master (89e4737) will increase coverage by 0%.
The diff coverage is 100%.

@@         Coverage Diff          @@
##           master   #35   +/-   ##
====================================
  Coverage      97%   98%           
====================================
  Files          11    11           
  Lines         286   305   +19     
  Branches       42    55   +13     
====================================
+ Hits          280   299   +19     
  Misses          3     3           
  Partials        3     3           
Impacted Files Coverage Δ
idesolver/idesolver.py 96% <100%> (+<1%) ⬆️
tests/test_misc.py 96% <100%> (+<1%) ⬆️
tests/test_solver_against_analytic_solutions.py 100% <100%> (ø)

@JoshKarpel

Copy link
Copy Markdown
Owner

@nbrucy I think I improved the dtype handling a little, in exchange for slightly less elegance. I also fixed a separate problem with coverage uploads that was breaking CI. CI is green and I like the changes, so let me know if you're good with the dtype handling and then I can merge.

@nbrucy

nbrucy commented Nov 19, 2020

Copy link
Copy Markdown
Contributor Author

It seems indeed to be more robust in case of inconsistencies between the types returned by the input functions.
All good for me !

@nbrucy
nbrucy marked this pull request as ready for review November 19, 2020 07:40
@JoshKarpel
JoshKarpel merged commit f799f85 into JoshKarpel:master Nov 19, 2020
@JoshKarpel

Copy link
Copy Markdown
Owner

Thank you so much @nbrucy ! This is a fantastic improvement. I'll try to cut a new release ASAP.

JoshKarpel added a commit that referenced this pull request Nov 19, 2020
JoshKarpel added a commit that referenced this pull request Nov 19, 2020
* add change log entry for #35

* resolve #25

* bump to v1.1.0

* fix up

* remove old codecov.yml

* explicitly list source dirs in .coveragerc

* more settings in .coveragerc

* add pypi badge
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Generalize to coupled IDEs

2 participants