Skip to content

Conversation

@rocky
Copy link
Member

@rocky rocky commented Jul 26, 2025

In addition to adding Hypergeometric2F1, we start moving code to mathics.eval.specialfns.hypergeom

Fixes #1187

Most of the eval functions have been moved out of mathics.builtin.specialfns.hypergeom. And in the process, we expand hyper results to match what WMA does more closely. Some prior erroneous evaluation was therefore corrected.

However, this PR is already large, so Hypergeometric2U will be handled separately.

Moving eval code for MeijerG, was attempted, but that causes a weird interaction with test/doc/doc_common.py, which somehow makes it think that hypergeom is included more than once.

@rocky rocky force-pushed the add-Hypergeometric2F1 branch from d686da3 to c46f005 Compare July 26, 2025 21:29
Also some results were corrected by making more use of SymPy's
hyperexpand function.
@rocky rocky force-pushed the add-Hypergeometric2F1 branch from 4e51c61 to 0c9c25e Compare July 27, 2025 00:36
@aravindh-krishnamoorthy
Copy link
Collaborator

I'll take a look soon.

@rocky rocky force-pushed the add-Hypergeometric2F1 branch from f136680 to a2f2cba Compare July 28, 2025 09:57
@rocky rocky force-pushed the add-Hypergeometric2F1 branch from a2f2cba to 1c84228 Compare July 28, 2025 09:59
@aravindh-krishnamoorthy
Copy link
Collaborator

aravindh-krishnamoorthy commented Jul 29, 2025

List of issues

This comment is just a log of potential issues found during review and is being worked on. The final comments will be added to the code or in a separate comment later.

Hypergeometric1F1[0,0,z]

  • Reported
  • Fixed

Hypergeometric1F1[0,0,z] is likely wrong.

In[2]:= Hypergeometric1F1[0,0,z]
Out[2]= E ^ z
In[3]:= Hypergeometric1F1[0,0,1]
Out[3]= E
In[4]:= Hypergeometric1F1[0,0,1.]
Out[4]= 2.71828
In[5]:= HypergeometricPFQ[{0},{0},1.]
Out[5]= 1.

Reference: https://functions.wolfram.com/HypergeometricFunctions/Hypergeometric1F1/03/01/03/0003/

@rocky
Copy link
Member Author

rocky commented Jul 29, 2025

Hypergeometric1F1[0,0,z] is likely wrong.

I wonder if it is not wrong but just different from WMA. There could be several valid solutions.

In[2]:= Hypergeometric1F1[0,0,z]
Out[2]= E ^ z
In[3]:= Hypergeometric1F1[0,0,1]
Out[3]= E
In[4]:= Hypergeometric1F1[0,0,1.]
Out[4]= 2.71828

I tracked down what's going on in the code, and these results are coming from SymPy's hyper() function. If there are several possible valid results, my guess is that this is what's going on.

For HypergeometricU[] , there is a rule:

HypergeometricU[0, c_, z_] = 1

So, one possibility is to add the same thing for Hypergeometric1F1 with a suitable comment explaining why this is done rather than take SymPy's answer. I am assuming there's no way to tell SymPy to return 1.

``mathematica
In[5]:= HypergeometricPFQ[{0},{0},1.]
Out[5]= 1.

Here, the difference has to do with whether the result is an Integer or a Machine number. This, I think, is easily fixed.

@rocky
Copy link
Member Author

rocky commented Jul 29, 2025

List of issues

In commit 101ee0a I've addressed these specific problems and a couple more.

However, I can see that getting everything the same as WMA, including its particular level of error handling and how it treats lists in HypergeometricPFQ would take a lot more work.

So we might have to note down problems, but defer handling these for later. Please use your judgment and experience. If something is important and wrong, let me know. If it is more of a quirky kind of behavior that feels more like this is just the way WMA happens to work, note it down, but we'll fix some other time.

(For example: Hypergeometric1F1[0.0, b, "A string is okay here?"] == 1.0000)

This comment is just a log of potential issues found during review and is being worked on. The final comments will be added to the code or in a separate comment later.

Hypergeometric1F1[0,0,z]

  • Reported

Hypergeometric1F1[0,0,z] is likely wrong.

In[2]:= Hypergeometric1F1[0,0,z]
Out[2]= E ^ z
In[3]:= Hypergeometric1F1[0,0,1]
Out[3]= E
In[4]:= Hypergeometric1F1[0,0,1.]
Out[4]= 2.71828
In[5]:= HypergeometricPFQ[{0},{0},1.]
Out[5]= 1.

@aravindh-krishnamoorthy
Copy link
Collaborator

So we might have to note down problems, but defer handling these for later. Please use your judgement and experience. If something is important and wrong, let me know. If it is more of a quirky kind of behavior that feels more like this is just the way WMA happens to work, note it down but we'll fix some other time.

Thank you and I fully agree. I will take a look with this advice in mind.

@aravindh-krishnamoorthy
Copy link
Collaborator

Very sorry, the latest commit is due messing around with the gh CLI. I think it's an empty commit, so I'm leaving it as is. However, I'm perfectly fine if you eliminate it in the next push @rocky

@rocky
Copy link
Member Author

rocky commented Jul 30, 2025

Very sorry, the latest commit is due messing around with the gh CLI. I think it's an empty commit, so I'm leaving it as is. However, I'm perfectly fine if you eliminate it in the next push @rocky

No problem. Would much rather have this than have apathy :-)

evaluation.message(
"HypergeometricPQF",
"hdiv",
Expression(Symbol("Hypergeometric"), a, b, z),
Copy link
Member Author

Choose a reason for hiding this comment

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

I will be revising this to use Pattern[] in the signature docstring as described in Mathics3/Mathics3-development-guide#44 to reduce the clumsiness of having to recreate an expression that already exists.

Copy link
Member Author

@rocky rocky Jul 31, 2025

Choose a reason for hiding this comment

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

I will be revising this to use Pattern[] in the signature docstring as described in Mathics3/mathics-development-guide#44 to reduce the clumsiness of having to recreate an expression that already exists.

@aravindh-krishnamoorthy #1440 is how to approach this by introspecting Python's call stack to pick out the Expression that must already exist. More specifically, line 209 would become:

from mathics.eval.stackframe import get_eval_Expression
... 
    evaluation.message("HypergeometricPFQ", "hdiv", get_eval_Expression())

But let's not hold up this PR due to the discussion of that PR and whether we might change the docstring to "Pattern[Expression, ... " as has also been proposed.

I will revise that separately based on the results of the discussion.

New options booleans ShowRewrites and ShowEvaluation can be added to
allow filtering TraceEvalation output to filter other either rewrites
rules or evaluation expressions. Presumably you don't want to filter
both.
@rocky rocky changed the title First cut at Hypergeometric2F1 First cut at Hypergeometric2F1 and some other Hypergeometric function revisions Jul 31, 2025
rocky and others added 6 commits July 31, 2025 21:03
Introduce `get_eval_Expression()`

`get_eval_Expression()` can be used in Mathics3 Builtin evaluation
methods to find the Expression that caused the evaluation to get
triggered.

mathics.file_io.files module converted to use this function to test
worthiness.
Also some results were corrected by making more use of SymPy's
hyperexpand function.
@rocky rocky merged commit 39dc575 into master Aug 2, 2025
14 checks passed
@rocky rocky deleted the add-Hypergeometric2F1 branch August 2, 2025 21:35
@rocky
Copy link
Member Author

rocky commented Aug 2, 2025

@aravindh-krishnamoorthy, this has been pending for a while, and I'm afraid the longer it remains pending, the harder it will be to merge. If there are concerns or comments, let me know.

@aravindh-krishnamoorthy
Copy link
Collaborator

I'll take a closer look tomorrow and let you know if any issues I find.

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.

Add Hypergeometric2F1 Builtin Function

3 participants