sympy / sympy

A computer algebra system written in pure Python
https://sympy.org/
Other
12.59k stars 4.33k forks source link

integrate don't return constant #11756

Open latot opened 7 years ago

latot commented 7 years ago

Hi all, well the actual integrate function don't returns the constant:

>>> integrate(x, x)
x**2/2

obvs, if the user send an interval of integration shouldn't exist the constant.

Well, would be great return a constant with the 'constant' assumption proposed here https://github.com/sympy/sympy/issues/8760 And maybe can choose in the integrate the constant name...

Thx. Cya.

Alsheh commented 7 years ago

Hi, I'm new here. I would be glad to work on this issue. However, I am not sure what the proper way of implementing your proposal is. Consider the following two scenarios:

1- The constant would be defined as a symbol in the integrate() function and returned as shown below. Also, the user would be able to choose the name of the constant when calling the integrate() function:

>>> integrate(x, x, constant = "c") 
x**2/2 + c
>>> integrate(x, x, constant = "c99")
x**2/2 + c99

2- The user must define the constant as symbol before calling the integrate() function:

>>> c = sympy.symbols("c")
>>> integrate(x, x, constant = c)
x**2/2 + c

Which one satisfies your request? If I am misinterpreting your suggestion, please let me know.

latot commented 7 years ago

Hi thx for you helping here, you interpret in the right way, now thinking a little, i think would be better instead set a constant name set a prefix name, and the value will be enumerated like:

integrate(x, x, constant = "c")
x**2/2 + c1
integrate(x, x, x, constant = "c")
x**3/6 + c1*x + c2

In some way i would prefer can set a constant from the integrate function, but how we can't control the grade of the integration that will do a mess in a grade more than 1.

So maybe we can add an extra feature to this, if the user want set the constants:

integrate(x, x, x, constant = ["k",  "h"])
x**3/6 + k*x + h
integrate(x, x, x, constant = ["k", x])
x**3/6 + (k + 1)*x

So, if constant is a string use it as prefix, if is array use it as constants when its necessary distinguish if is a string or symbol or number, in this last case its necessary check the length of the array, because it need to be equal to the grade (x grade of integration, x length of array).

I think in first place confirm this with some sympy member to know they opinion.

@smichr or @jksuom or @asmeurer can say someone your opinion about this please?

Thx. Cya.

latot commented 7 years ago

Note, i think if constant don't is passed, the default value should be "C", to do the same behavior as dsolve.

Alsheh commented 7 years ago

Thanks @latot for the helpful response and I apologize for the delay. I need further clarification on the following points:

1- Please elaborate on some of the problems you mentioned that might arise for a grade more than 1 when setting the constant name as a prefix name. Perhaps an example that shows the problem can be helpful.

2- Also, I'd appreciate it if you could explain to me what you mean by the grade of the integration.

3- Please explain briefly the steps involved to the get the result in the last example in your second post:

>>>integrate(x, x, x, constant = ["k", x])
x**3/6 + (k + 1)*x

Please forgive me if any of the aforementioned points seem too abvious. I'm here to learn and contribute to the best of my abilities.

Thanks.

latot commented 7 years ago

Hi!, i'll try explain this, in order, 2, 1, 3:

2) In derivatives you have the grade, its normally the number of times is derived, in integration is the same, so is number of times we integrate a function with some vars: integrate(x, x, x) have 2 grades, because we are integrating x in x 2 times. Normally this concept is used independent of what vars you are integrating, ex: integrate(x, x, y) have 2 grades too.

Checking an English dictionary, grades == degrees, please say me if have different meanings by context. (maybe this cause this confusion).

1) Here i can see 2 problems, one here: https://github.com/sympy/sympy/issues/11763, the next:

C1 = symbols("C1")
integrate(C1, C1)
C1**2/2 + C1

This part is similar to the issue, is basically be careful, you need check if the constant expression exist in the function, because you shouldn't use the same name if exist, in this case the ideal output should be:

integrate(C1, C1)
C1**2/2 + C2

Like if exist the var you only need add one to the var, this is because the default prefix "C" have a collision with the user vars. Other way can be use Dummy, but i think will be too confuse...

3) sorry for don't write this part:

integrate(x, x, x, constant = ["k", x])
integrate(x**2/2 + k, x, constant = x)
x**3/6 + k*x + x -> x**3/6 + x*(k + 1)

In this case the user set a constant equal as a symbol already exist in the function.

Thx. Cya.

asmeurer commented 7 years ago

My opinion in the past has been that integrate shouldn't do this. Consider multivariate integrals. For integrate(x*y, x), the answer is x**2/2*y + C. But should C depend on y? What about integrate(x*y, x, y)? Even integrate(x, x, x) should have two distinct constants (the answer would be x**3/6 + C1*x + C2).

So my view has always been that if you want to track constants, you should use dsolve, or pdsolve for the multivariate case (granted pdsolve still needs a lot of work to be useful). It is some work to convert an integral into a differential equation (some functions to help here would be nice). integrate(f(x), x) is equivalent to solving Eq(g(x).diff(x), f(x)) for g(x), i.e., dsolve(Eq(g(x).diff(x), f(x)), g(x)). I know I've written about this in the past (if you search the issue tracker you might be able to find it).

By the way, I don't understand your integrate(x, x, x, constant = ["k", x]) example, and its supposed output x**3/6 + (k + 1)*x. How does the constant = ["k", x] result in C1 = k + 1 and C2 = 0?

Regarding "grades", I've never seen that word used in this context. "Degree" is more common, but I would call it "order", as that's the term used by derivatives and differential equations, and it distinguishes it from the degree of a polynomial.

latot commented 7 years ago

Hi!, thx for your opinion, now, constants depends of x and y? yes it depends, all math expressions are expressed in like k == x, so following your example, integrate(x*y, x) is equal to x**2/2*y + C but that only the half of expression, x**2/2*y + C == K, where all vars depends of the others, thinking in other way the constants in any equation represent a proportions, is true is a number but it only will be true in their own context, an example, x*y==z, now this is 1==z/(x*y), as you can see in lhs we have 1, number, constant, but don't is independent of the others expressions, its like a restriction.

Now, i'm rethinking part of this, but first, Thx clarifying the context concept, now i'll use order instead and i need edit the other comments to avoid confusions, i think we shouldn't restrict the constants to be numbers, only for one reason, that will put a restriction in the integral concept, i said this before, math is interpretations, depending of what we want, and how we interpret it we use it in one way or other, so exist cases where the constant don't need to be a constant in the analysis, is true this don't will respect the strict concept of integral but the will be more free to use it with what it need.

About if Integral should return a constant or not, basically if you think don't should return is a valid way, but if you do it i think Integral should lock return the primitive, because is incomplete, its like the NotImplementedError, if you have a non-implemented function, and you write the 50% of the algorithm, you probably will not enable it and return a wrong or incomplete result, following that logic rute, we can expand concepts to improve, but if we restrict someone we need disable the parts according to it, if is decided change in this way the wiki will need changes to send the user to get the primitives in dsolve instead, maybe instead of a non-implemented error, say use dsolve, or call dsolve from Integral function, i don't like to much lock the primitive from integral function, but i think its better lock it and know what function have what we need instead of get an incomplete result (sorry if i write this in a hard way).

Explaining a little my example of above, integrate(x, x, x, constant = ["k", x]), C1 = k and C2 = x, when you replace and compact a little the expression you get this result, this is an example of non-strict integral concept, but a valid integral interpretation.

Only to be clear, lets use an example, i want analyze the amount of water in a central, in the time enters t L/s, but i want analyze the amount of water with the special case of the flow of the time is the same as the water exist in the first place in the central, so if at one time we have 1 L/s the central will have 1L, and if we have 5 L/s the central will have 5L in the start point, so writing this: Integral(t, t, constant=t) == t**2/2 + t Now we have an expression to can analyze this case, and as you can see here the constant is a variable.

Thx. Cya.

asmeurer commented 7 years ago

Why do you have examples where the constant is the integration variable? The constant should, by definition, be constant with respect to the integration variable. Making it nonconstant makes it give a wrong answer. diff(t**2/2 + t, t) does not equal t.

Regarding your comments about dependence, in sympy, different symbols are assumed to not depend on one another, for the purposes of differentiation/integration. For C to depend on y it needs to be a function C(y).

latot commented 7 years ago

Hi, i think its necessary split some things, first, we are agree the primitive should respect this: diff(F)=f now, this is why i say, all of this depends of how we interpret or use math, in the strict case to respect the relation C must be a constant, but this don't is always true to any interpretation, my examples confirm this, if i change the interpretation of the integral obvs then the relations don't need to be respected, this is the user choice.

Now, be a constant in a expression, is different to be a constant alone, 2 is a constant, but in ex 2 = a 2 is a constant too, but it depends of a, always with the condition to respect the relation, if i replace a with 3 i'll don't respect it and the expression is relative invalid. So to summarize this part, when we say something is constant?, this is when the independent expression, not in a relation like eq, don't have any variable. Ex: 2 is constant because don't depends of any variable var, but in 2 == a, 2 depends of a to can set the expression, and in the same time is constant.

sylee957 commented 3 years ago

In my opinion, one of the application of integration constant that can't be done via dsolve is that it allows to combine logarithms easily. log(x)+log(y) = log(x*y) doesn't simplify when x, y are complex variables, but with integration constant, log(x)+log(y) + C = log(x*y) + C because the integration constant can shift 2*pi*I arbitrarily shift the branches of the logarithm.

I think that some other identities like log(e**x) = x, arctan(tan(x)) = x should be true under integration constants even if they don't hold when we consider them as complex analysis. I haven't surveyed about this identities fully for elementary functions, but there should be more. So one application of integration constant is that it should be used as a key when simplifying integration results.

The only thing I've not concluded is defining integration constant for multivariate functions Maybe I think that nullary function Function('C')() can be used as a basic integration constants over univariate functions such that it can solve the problem of using same consistent classes of integration constant over multivariate functions. Mathematica 12 is able to generate integration constants so we should also survey their approach https://www.wolfram.com/language/12/core-calculus/generate-constants-of-integration-and-summation.html.en?footer=lang

And we also need to survey about mathematics that integration constant is not actually a true constant if it is separately over discontinuities like in https://golem.ph.utexas.edu/category/2012/03/reader_survey_logx_c.html, in this case, the integration constant can itself depend on the integration variable in piecewise way. But even that may not work with complex functions. for example, in https://blog.wolfram.com/2008/01/19/mathematica-and-the-fundamental-theorem-of-calculus/, how are you going to set the integration separately all over the complex plane?

sylee957 commented 3 years ago

In the Davenport's paper, it notes that the algebraic definition of integration constant can range over heaviside functions, which is not a constant analytically, and this is more natural conclusion for the result of risch integration.