Why Julia symbolic generate random result for symbolic integration?

edit: added this as issue. Link is

original question:

I am not able to understand this. I have a script that tests one integration problem using the symbolic Julia and symbolic integrator.

I noticed I get different answers each time I run the same script! This makes no sense.

Setup: Windows 10. Julia 1.8. Here are some examples

>julia bug_2.jl
before calling integrate
anti       = 0
n_unsolved = 7.870812040507434e12((x - (1//2))^-1) + 0.3129295650227808(((3//5) + x)^-2) + 3.3697484260488335e12(((4//9) + (4//3)*x + x^2)^-1) + 3.935406020253715e12(((1//4) + x^2 - x)^-1) + 5.054622639072726e12x*(((4//9) + (4//3)*x + x^2)^-1) - 9.965866637814543(((3//5) + x)^-1) - 5.054622639062742e12(((2//3) + x)^-1) - 7.870812040507433e12x*(((1//4) + x^2 - x)^-1)
residual_error = Inf

>julia bug_2.jl
before calling integrate
anti       = 0
n_unsolved = 0
residual_error = 0

>julia bug_2.jl
before calling integrate
anti       = 0.328336208533607log((3//5) + x)
n_unsolved = 0
residual_error = 8.892745078570921e-17

>julia bug_2.jl
before calling integrate
anti       = 0
n_unsolved = 0.0062035665227498805((x - (1//2))^-2) + 0.30822457512509605(((3//5) + x)^-2) + 1.91289293028192e13(((2//3) + x)^-1) - 0.024564014848914694((x - (1//2))^-1) - 9.043247646362328(((3//5) + x)^-1) - 1.2752619535206465e13(((4//9) + (4//3)*x + x^2)^-1) - 1.9128929302810082e13x*(((4//9) + (4//3)*x + x^2)^-1)
residual_error = Inf

>julia bug_2.jl
before calling integrate
anti       = 0
n_unsolved = 0
residual_error = 0


>julia bug_2.jl
before calling integrate
anti       = 0
n_unsolved = 0.42972286411222066(((3//5) + x)^-2) + 1.1185704789344634e15(((2//3) + x)^-1) + 2.148487268951736e13x*(((1//4) + x^2 - x)^-1) - 2.1484872689517336e13((x - (1//2))^-1) - 31.70781106970997(((3//5) + x)^-1) - 1.0742436344758682e13(((1//4) + x^2 - x)^-1) - 7.457136526229525e14(((4//9) + (4//3)*x + x^2)^-1) - 1.1185704789344316e15x*(((4//9) + (4//3)*x + x^2)^-1)
residual_error = Inf

The above where all run from a new command line windows (DOS window) in windows 10.

You see, different answers for same input. sometime same answer (zero in the above example) is repeated if I run it few more time). Here is the script

using Symbolics
using SymbolicNumericIntegration
using Dates
using SpecialFunctions

@syms x

println("before calling integrate")

anti,n_unsolved,residual_error =integrate(1 / (((1 - 2x)^3)*((2 + 3x)^3)*((3 + 5x)^2)),x)
 
println("anti       = ",anti)
println("n_unsolved = ",n_unsolved)
println("residual_error = ",residual_error)

Anyone knows what is going on? How could different solution result each time integrate is called? How does one know which is the correct one?

Same thing happens on Linux using Julia 1.8. Am I doing something wrong? Is this a bug I need to enter? Is there a setting or an option one can use to make sure same result is generated each time?

Another question on the above, for the case where the antiderivative (anti) is zero and the number of terms not integrated (n_unsolved) is also zero. How could both of these be zero at same time? When n_unsolved is zero, it means all terms were successfully integrated. Therefore the antiderivative can not be zero. What Am I missing here?

Could someone please try to reproduce this?

Also getting varying results

❯ julia --project test.jl
before calling integrate
anti       = 0
n_unsolved = 0
residual_error = 0

❯ julia --project test.jl
before calling integrate
anti       = 0
n_unsolved = 3.5000251903659673e12((x - (1//2))^-1) + 8.213307863915952(((9//25) + (6//5)*x + x^2)^-1) + 1.7500125951829858e12(((1//4) + x^2 - x)^-1) + 14.438342445070925x*(((9//25) + (6//5)*x + x^2)^-1) - 0.48867892205349495(((2//3) + x)^-2) - 14.474030959415762(((2//3) + x)^-1) - 3.500025190365968e12x*(((1//4) + x^2 - x)^-1)
residual_error = Inf

❯ julia --project test.jl
before calling integrate
anti       = 0
n_unsolved = 0.4961406841639416(((3//5) + x)^-2) + 9.299806708499975e13(((4//9) + (4//3)*x + x^2)^-1) + 1.0090447083224806e14x*(((1//4) + x^2 - x)^-1) + 1.3949710062749917e14x*(((4//9) + (4//3)*x + x^2)^-1) - 1.009044708322481e14((x - (1//2))^-1) - 14.091755550709264(((3//5) + x)^-1) - 1.3949710062748486e14(((2//3) + x)^-1) - 5.045223541612403e13(((1//4) + x^2 - x)^-1)
residual_error = Inf
1 Like

thanks for verification. I thought I am doing something wrong.

Will submit an issue on this in this case.

I think I find a workaround. But need someone to please verify it on their PC.

By setting random seed to a fixed value, say 12 before calling integrate, now the same result is obtained each time. Here is the updated script bug_2.jl

using Symbolics
using SymbolicNumericIntegration
using Dates
import Random

Random.seed!(12) #must do this in order to reproduce same result

@syms x

println("before calling integrate")

time1 = now();
anti,n_unsolved,residual_error =integrate(1 / (((1 - 2x)^3)*((2 + 3x)^3)*((3 + 5x)^2)),x)
time2 = now();
time_used_in_sec = (Dates.DateTime(time2)-Dates.DateTime(time1))/ Millisecond(1) * (1 / 1000)

println("time used =",time_used_in_sec)
 
println("anti       = ",anti)
println("n_unsolved = ",n_unsolved)
println("residual_error = ",residual_error)

And now when I run the script number of times, I get same result each time:

>julia bug_2.jl
before calling integrate
time used =70.639
anti       = 0
n_unsolved = 1.6602780101345385e13((x - (1//2))^-1) + 2.8289042577780735e15(((3//5) + x)^-1) + 8.301390050672688e12(((1//4) + x^2 - x)^-1) - 1.2230893145047396e6(((4//9) + (4//3)*x + x^2)^-1) - 1.697342553676207e15(((9//25) + (6//5)*x + x^2)^-1) - 1.7402011587196218e6x*(((4//9) + (4//3)*x + x^2)^-1) - 1.6602780101345375e13x*(((1//4) + x^2 - x)^-1) - 2.82890425603774e15x*(((9//25) + (6//5)*x + x^2)^-1)
residual_error = Inf

>julia bug_2.jl
before calling integrate
time used =71.749
anti       = 0
n_unsolved = 1.6602780101345385e13((x - (1//2))^-1) + 2.8289042577780735e15(((3//5) + x)^-1) + 8.301390050672688e12(((1//4) + x^2 - x)^-1) - 1.2230893145047396e6(((4//9) + (4//3)*x + x^2)^-1) - 1.697342553676207e15(((9//25) + (6//5)*x + x^2)^-1) - 1.7402011587196218e6x*(((4//9) + (4//3)*x + x^2)^-1) - 1.6602780101345375e13x*(((1//4) + x^2 - x)^-1) - 2.82890425603774e15x*(((9//25) + (6//5)*x + x^2)^-1)
residual_error = Inf

>julia bug_2.jl
before calling integrate
time used =69.586
anti       = 0
n_unsolved = 1.6602780101345385e13((x - (1//2))^-1) + 2.8289042577780735e15(((3//5) + x)^-1) + 8.301390050672688e12(((1//4) + x^2 - x)^-1) - 1.2230893145047396e6(((4//9) + (4//3)*x + x^2)^-1) - 1.697342553676207e15(((9//25) + (6//5)*x + x^2)^-1) - 1.7402011587196218e6x*(((4//9) + (4//3)*x + x^2)^-1) - 1.6602780101345375e13x*(((1//4) + x^2 - x)^-1) - 2.82890425603774e15x*(((9//25) + (6//5)*x + x^2)^-1)
residual_error = Inf

Can someone please verify this? It is important I get same result each time.

–Nasser

Getting the same results as you.

It actually mentions in the docs that it uses a randomized algorithm so I guess that is expected. Though I’m not sure why it is desirable to have a randomized algorithm for that.

Yes, I did see that it uses randomized algorithm. That is why I changed my code to use seed() to fix the result. I just wanted to make sure it gives same result on other platform just in case.

Thanks for checking.

Try decreasing the tolerances.

Thanks for suggestion. I tried that. I used abstol=0.01 and abstol=0.1 and few other values. But the result still changes from one run to the other.

I had to use a fixed random seed value (say 99) to insure same result comes out each time.