Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate Taylor series #1298

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open

Generate Taylor series #1298

wants to merge 18 commits into from

Conversation

hersle
Copy link
Contributor

@hersle hersle commented Oct 7, 2024

Is something like this suited for Symbolics.jl?

@hersle hersle marked this pull request as draft October 7, 2024 18:55
@codecov-commenter
Copy link

codecov-commenter commented Oct 7, 2024

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

Attention: Patch coverage is 0% with 37 lines in your changes missing coverage. Please review.

Project coverage is 38.16%. Comparing base (8cb25a8) to head (4f21ba0).
Report is 47 commits behind head on master.

Files with missing lines Patch % Lines
src/taylor.jl 0.00% 37 Missing ⚠️

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1298      +/-   ##
==========================================
+ Coverage   30.06%   38.16%   +8.09%     
==========================================
  Files          47       48       +1     
  Lines        4576     4698     +122     
==========================================
+ Hits         1376     1793     +417     
+ Misses       3200     2905     -295     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@hersle
Copy link
Contributor Author

hersle commented Oct 7, 2024

One problem is that the coefficients come out as floats (I want them to be rationals) because of substitute(..., x => 0). A minimal example:

julia> @variables x
1-element Vector{Num}:
 x

julia> y = expand_derivatives(Differential(x)(sin(x)) / 2)
(1//2)*cos(x)

julia> substitute(y, x => 0)
0.5

Using fold does not help:

julia> substitute(y, x => 0, fold=false)
(1//2)*cos(0)

julia> substitute(y, x => 0, fold=true)
0.5

The issue is that e.g. cos(0) evaluates to the float 1.0, so (1//2) * 1.0 is converted to 0.5 (see #1299). Is there an easy way to fix this?

src/taylor.jl Outdated Show resolved Hide resolved
@ChrisRackauckas
Copy link
Member

This does seem like a good thing for Symbolics.

@shashi do you know how to make substitute not convert to float?

@hersle
Copy link
Contributor Author

hersle commented Oct 8, 2024

One (far from perfect) solution is to rationalize() float coefficients into rational numbers. This seems to work well for the tests, except for e.g. the first irrational term in the series for acos(x) = π/2 + ..., which becomes 122925461//78256779.

@hersle
Copy link
Contributor Author

hersle commented Oct 8, 2024

There is also TaylorSeries.jl, which could perhaps compose with Symbolics.jl.

@hersle hersle force-pushed the taylor branch 2 times, most recently from 0f40858 to cb9343d Compare October 8, 2024 21:59
@hersle
Copy link
Contributor Author

hersle commented Oct 10, 2024

I have made quite a hefty rewrite of the perturbation example. My goal has been to significantly shorten it and better display the features of Symbolics.jl, and particularly the power of the new Taylor series functions.

I hope I have not lost the spirit of the old tutorial. Please let me know if you want me to restore some of it.

@hersle hersle marked this pull request as ready for review October 10, 2024 11:50
@hersle
Copy link
Contributor Author

hersle commented Oct 10, 2024

I would appreciate it if someone looks at this :) Suggestions are welcome! Particularly regarding how you think the public Taylor series interface should work, i.e. the current series, taylor and taylor_coeff functions.

cc @karlwessel and #1292 and SciML/ModelingToolkit.jl#3098

@karlwessel
Copy link

I love to take a more closer look at this, but not before mid of next week.

@karlwessel
Copy link

There is also TaylorSeries.jl, which could perhaps compose with Symbolics.jl.

This is what makes evaluating the usefulness of this PR complicated for me.
The package TaylorSeries and Symbolics + this PR seem to overlap pretty heavily:

  • both implement some notion of a variable,
  • both implement derivatives for basic julia functions,
  • both allow to define Taylor series using this functionality.

What does TaylorSeries provide that wouldn't be easily doable using this PR?

  • probably a lot of ease of use functions like evaluating Taylor series
  • multivariate Taylor series
  • integration of Taylor series

What does Symbolics + this PR provide that wouldn't be easily doable with TaylorSeries?

  • expansion of user defined functions around different variables
  • the whole Symbolics ecosystem

In a perfect World:

  1. should TaylorSeries use Symbolics to implement all of its stuff
  2. should TaylorSeries just work with Symbolics?
  3. should this PR use Symbolics to implement its functionality?

In our world: Is it ok for them to just live happily side by side? If yes: is this really worth adding to Symbolics, or would it be enough to add a tutorial that shows how to expand a function as a Taylor series?

z[0] + z[1]*(-2 + ϵ) + z[2]*((-2 + ϵ)^2) + z[3]*((-2 + ϵ)^3)
```
"""
function series(y, x, x0, ns; name = nameof(y))

Choose a reason for hiding this comment

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

This won't work for making a taylor series for functions, like for the perturbation theory for differential equations example. Maybe adding a method like this would work:

series(coeff, x) = sum([x^(i-1)*y for (i, y) in enumerate(coeff)])

That could be used like

@variables t, (y(t))[1:3] epsilon
series(y, epsilon)

I think that function could also be used to implement all of the other use cases.

  • series with $x_0 \ne 0$: series(y .+ x0, epsilon)
  • series with first coeff zero: series([0; y], epsilon)

Copy link

@karlwessel karlwessel left a comment

Choose a reason for hiding this comment

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

I am mixed about the changes. A lot of the explanations in the text have become much clearer, especially on describing perturbation theory and its advantages (for CAS and in general).
It also does a good job to show of the new implemented features for working with Taylor series.

However, since the previous version had to implement all of the taylor specific features by hand it was easier for me to understand the procedure and adapt it for my own problem. Now if one of the new library methods fails for my own specific problem I wouldn't really know what to do. That of course wouldn't be a problem if the new methods just work for everything.


The “hello world!” analog of perturbation problems is to find a real solution $x$ to the quintic (fifth-order) equation
```@example perturb
using Symbolics # load Symbolics.jl

Choose a reason for hiding this comment

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

I think the comments are not necessary here. This is self explanatory enough:

using Symbolics
@variables x
quintic = x^5 + x ~ 1

```
According to Abel's theorem, a general quintic equation does not have a closed form solution. But we can easily solve it numerically using Newton's method (here implemented for simplicity, and not performance):
```@example perturb
function solve_newton(eq, x, x₀; abstol=1e-8, maxiters=50)

Choose a reason for hiding this comment

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

I think introducing a fully blown, automatic solver function is to much at this point. I think it would be better to keep solving it step by step and then maybe introduce and use this method to solve the second example.

Or maybe even do all of the steps again and let the reader realize the generality of the procedure and let them implement a generic method themself.

@karlwessel
Copy link

I would suggest to split this PR into multiple steps/stages.

In the first step introduce and implement easy to understand simple versions of the Taylor series methods in the perturbation example, specific to the perturbation example.

In the next step see how those methods can be used or adapted to work for the example on perturbation theory for ODEs in ModelingToolkit.

And last, if those methods have proven to work in the examples and maybe have been used to solve other perturbation problems (multivariate equations, PDEs, field equations) we can use that experience to decide how and where to add those methods to the Symbolics library or its ecosystem.

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.

4 participants