Skip to content

Conversation

tttc3
Copy link
Contributor

@tttc3 tttc3 commented Jun 21, 2022

References to other Issues or PRs

Provides parametric priting support as originally introduced in #23627

Brief description of what is fixed or changed

Provides parametric support for all children of AbstractPythonCodePrinter.

Other comments

Responses to the concerns raised in #23627 will be edited in here shortly.

Release Notes

  • utilities
    • Added parametric option to lambdify, allowing numeric values in the lambdified expression to be changed after the function has been generated. For example, f, params = lambdify([x,y], 1.0*cos(x) + 3.2*y, parametric=True) would generate a function of the form:
      def _lambdifygenerated(x, y, params=params):
          [params_0, params_1] = params
          return params_0*cos(x) + params_1*y
  • printing
    • Added parametric setting to AbstractPythonCodePrinter, allowing numeric values in child printers to be printed as placeholders, rather than their true numeric values. Example: PythonCodePrinter(settings={"parametric": True}).doprint(1.0*cos(x) + 3.2*y) would return "params_0*cos(x)+params_1*y".

@sympy-bot
Copy link

sympy-bot commented Jun 21, 2022

Hi, I am the SymPy bot (v167). I'm here to help you write a release notes entry. Please read the guide on how to write release notes.

Your release notes are in good order.

Here is what the release notes will look like:

  • printing

    • Added parametric setting to AbstractPythonCodePrinter, allowing numeric values in child printers to be printed as placeholders, rather than their true numeric values. Example: PythonCodePrinter(settings={"parametric": True}).doprint(1.0*cos(x) + 3.2*y) would return "params_0*cos(x)+params_1*y". (#23661 by @tttc3)
  • utilities

    • Added parametric option to lambdify, allowing numeric values in the lambdified expression to be changed after the function has been generated. For example, f, params = lambdify([x,y], 1.0*cos(x) + 3.2*y, parametric=True) would generate a function of the form:

      def _lambdifygenerated(x, y, params=params):
          [params_0, params_1] = params
          return params_0*cos(x) + params_1*y

      (#23661 by @tttc3)

This will be added to https://github.com/sympy/sympy/wiki/Release-Notes-for-1.11.

Click here to see the pull request description that was parsed.
#### References to other Issues or PRs
Provides parametric priting support as originally introduced in #23627

#### Brief description of what is fixed or changed
Provides parametric support for all children of `AbstractPythonCodePrinter`.

#### Other comments
Responses to the concerns raised in #23627 will be edited in here shortly.

#### Release Notes
<!-- BEGIN RELEASE NOTES -->
- utilities
    - Added parametric option to lambdify, allowing numeric values in the lambdified expression to be changed after the function has been generated. For example, `f, params = lambdify([x,y], 1.0*cos(x) + 3.2*y, parametric=True)` would generate a function of the form:
      ```Python
      def _lambdifygenerated(x, y, params=params):
          [params_0, params_1] = params
          return params_0*cos(x) + params_1*y
      ```
- printing
    - Added parametric setting to AbstractPythonCodePrinter, allowing numeric values in child printers to be printed as placeholders, rather than their true numeric values. Example: `PythonCodePrinter(settings={"parametric": True}).doprint(1.0*cos(x) + 3.2*y)` would return `"params_0*cos(x)+params_1*y"`.
<!-- END RELEASE NOTES -->

@tttc3 tttc3 mentioned this pull request Jun 21, 2022
@asmeurer
Copy link
Member

In your example, f, params = lambdify([x,y], 1*cos(x) + 3.2*y, parametric=True), how are you supposed to know which parameter is which? Just because you typed 1*cos(x) + 3.2*y doesn't mean that SymPy will keep it in that order. SymPy sorts Add arguments, so it could also be represented as 3.2*y + 1*cos(x). Also, the 1*cos(x) does nothing. SymPy automatically converts this to just cos(x). Does this example actually work as written?

I'm trying to understand what the point of doing this is vs. just passing additional arguments to lambdify explicitly. We could have a function that automatically converts numbers in an expression into symbols which you could use before passing it to lambdify (something like that might even already exist).

@tttc3
Copy link
Contributor Author

tttc3 commented Jun 21, 2022

I've just checked, and you are correct, the example doesn't work unless 1 is changed to 1.0.

The specific use case I had envisioned for the current implementation was as follows: I have dynamically created an expression with some intial values e.g 2.0*x + 1.0. I want to optimise the constants in this expression, using the defaults as a starting point. I don't really need to know anything about the position of the constants/parameters, only a way to modify/update them each time I call the lambdified version of the expression.

However, I think your suggestion to replace the constants with symbols before inputing to lambdify may be better. As you pointed out, parameter order cannot be enforced in the currently proposed method. Would it be possible to have default values for those symbols that replace the constants using this method though?

@tttc3 tttc3 marked this pull request as draft June 22, 2022 10:47
@bjodah
Copy link
Member

bjodah commented Jun 30, 2022

@tttc3 perhaps we could have lambdify generate a function where parameters are passed as keyword arguments, that would allow a natural place for default values. Though I have to say that lambdify is already a Jack of all trades, so perhaps the functionality would make more sense either as something that wraps the lambdified function object, or as a parallel implementation...

@tttc3
Copy link
Contributor Author

tttc3 commented Sep 25, 2023

It has been a long time since I last considered the functionality here. I no longer have an immediate use for this functionality, and as no other users have indicated a desire to have such a feature, I think it is same to close this pull.

For future readers, the beautifully simple https://github.com/google/sympy2jax effectively provides the functionality described above specifically for JAX expressions.

@tttc3 tttc3 closed this Sep 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants