mitmath/computational-thinking

hw6: `euler_integrate_step` test

icweaver opened this issue · 4 comments

Hi, based on the discussion in the class discord (copied below), should these conditionals be switched/tweaked?
https://github.com/mitmath/18S191/blob/1dddcc9cb2cb88dce5fb17dea23b67a7e70da9b7/homework/homework6/hw6.jl#L818-L821

I.e., to something like this?

if result  1462
	correct()
elseif result  6358
	almost(md"Use ``f'(a)``, not ``f'(a+h)``.")

Copied from discord server:

user1 Yesterday at 11:22 AM
Hi guys, silly question, but why in the Euler step they make us use:

Use f'(a+h) instead of f'(a)?

I've tried to infer it geometrically, but I get lost in the approximation details - does someone has a video/resource that explains the rationale behind this trick to improving accuracy?

Is it just because we're integrating 'forward' ?

IanWeaver Yesterday at 6:50 PM
Oh, I totally missed that! Thanks for pointing that out, I think they might have just hard-coded the wrong branches in the test, but this would definitely be something worth following up with the instructors about. For example, I think 6358 and 1462 might be switched, and that the almost message should read "Use f'(a), not f'(a + h)." instead. The later implementations of this method also look to agree with this.

There are certainly different numerical methods though where you can use the slope at different points, RK4 probably being the most famous example. You can also just use the slope at the end of the step, but that would then turn it into an implicit scheme known as backward Euler. In general, this would require a root-finding method or fixed-point iteration to solve. If you happen to be interested in those kinds of methods, I made a brief write up about it here, but I haven't updated that package in a while:
https://spacejam.readthedocs.io/en/latest/background.html#background

One of the nice things about implicit methods is how stable they are, but I think that is outside the scope of this homework assignment, which is another reason why I think the above problem you brought up might just be a typo.

Finally, for a quick intro to numerical methods, you can't beat the OGs:
https://www.youtube.com/watch?v=RGtCw5E7gBc
https://www.youtube.com/watch?v=q87L9R9v274(edited)
[6:53 PM]
I'll go ahead and open an issue about this and link to the discussion here 
Link to issue: #61

user2 Yesterday at 7:04 PM
yea, i was also weirded out by that because they used f'(a) in the preceding equation

fonsp commented

Can you post a copy of the discussion?

For sure, just added

fonsp commented

Thanks for including, but can you explain briefly why it should be reversed?

Sure! It's my understanding that the standard explicit Euler method just uses the information at the beginning of the time step, as stated in the homework assignment:
https://github.com/mitmath/18S191/blob/a5cf7fd3b04d6d285bcd1239d3dcb009342a26fe/homework/homework6/hw6.jl#L210-L212

The test seems to think that we should use the slope at the end of the step: f(a+h) ≃ f(a) + hf'(a + h) instead of the beginning: f(a+h) ≃ f(a) + hf'(a). I don't think this slight modification was mentioned in the homework assignment, which made me think that it probably wasn't the intention to take us down the path of explicit vs implicit numerical methods.

As a sanity check, I just plugged in the test values to both versions, which appear flipped to what it should actually be testing, assuming only the explicit Euler method should be implemented. So, for result = euler_integrate_step(fprime=x -> x^2, fa=10, a=11, h=12) in the test (kwargs added for my own sanity), this corresponds to:

result = f(a) + h*f'(a + h) = 6358

for the correct branch and:

result = f(a) + h*f'(a) = 1462

for the almost branch, when really it should be the other way around.