7.2 Julia

  1. see https://symbolicnumericintegration.sciml.ai/dev/

    It says:

    "Function integrate returns the integral of a univariate expression with constant real or complex coefficients. integrate returns a tuple with three values. The first one is the solved integral, the second one is the sum of the unsolved terms, and the third value is the residual error. If integrate is successful, the unsolved portion is reported as 0."

    see also the paper

    https://arxiv.org/abs/2201.12468

    import Pkg; Pkg.add("Symbolics")` to install the Symbolics package. 
     
    julia> using SymbolicNumericIntegration 
      Package SymbolicNumericIntegration not found, but a package named SymbolicNumericIntegration is available from a registry. 
      Install package? 
        (@v1.7) pkg> add SymbolicNumericIntegration 
      (y/n) [y]: 
     
    Precompiling project... 
      64 dependencies successfully precompiled in 539 seconds (110 already precompiled)
     
    

    To do integration, the commands are (where it is assumed the integrand say 3*x is in file called input.txt in same folder

    using Symbolics 
    using SymbolicNumericIntegration 
    using Dates 
    using CSV 
    using DataFrames 
    using Elliptic 
    using Elliptic.Jacobi 
    using SpecialFunctions 
     
    @syms x z y t a 
     
    integrand = include("input.txt") 
    integrate(integrand,x) 
     
    julia> @time integrate(3*sin(x)+x*cos(x),x) 
         0.138087 seconds (19.18 k allocations: 9.491 MiB) 
        (x*sin(x) - 2cos(x), 0, 0)
     
    

    To measure time used

     
    julia> time1 = now(); 
     
    julia> anti,n_unsolved,residual_error = integrate(3*sin(x)+x*cos(x),x) 
    (x*sin(x) - 2cos(x), 0, 0) 
     
    julia> time2 = now(); 
     
    julia> (Dates.DateTime(time2)-Dates.DateTime(time1))/ Millisecond(1) * (1 / 1000) 
    0.197 
     
    julia> anti 
    x*sin(x) - 2cos(x)
     
    

    To read the integrals, create text file like this (say input.txt)

    [[3*x,x,0,3/2*x^2], 
    [4*x,x,0,2*x^2]]
     
    

    Then do

    data=include("input.txt") 
     
    julia> length(data) 
    2 
     
    julia> data[1][1] 
    3x 
     
    julia> data[2][1] 
    4x
     
    

    Hence to loop over all integrands in file, do

    data=include("input.txt") 
     
    julia> for n in 1:length(data) 
           println(integrate(data[n][1],data[n][2])) 
           end 
    ((3//2)*(x^2), 0, 0) 
    (2(x^2), 0, 0)
     
    

    To read all lines as strings do

    data=readlines("input.txt") 
     
    julia> data[2] 
    "[x*sqrt(1 + 3*x), x, 2]," 
     
    julia> data[3] 
    "[x^2*sqrt(1 + x), x, 2],"
     
    

    This gives error

    expr=1/((1 + x)^2*sqrt(2)*sqrt(-im + x^2)) + 1/((1 + x)^2*sqrt(2)*sqrt(im + x^2)) 
    ERROR: TypeError: non-boolean (Num) used in boolean context 
    Stacktrace: 
     [1] sqrt(z::Complex{Num}) 
       @ Base ./complex.jl:501 
     [2] top-level scope 
       @ REPL[115]:1
     
    

    A better way to read the integrals from file is this. The file has to be in this format

    [x^2,x] 
    [x^3,x] 
    . 
    . 
    . 
    [sin(x),x]
     
    

    Then do

    using Symbolics 
    using SymbolicNumericIntegration 
    using Dates 
    using SpecialFunctions 
    using SymbolicUtils 
     
    @syms x z y t a 
    @syms _C0 _C1 _C2 _C3 _C4 _C5 _C6 _C7 _C8 _C9 
     
    #import Base: exp 
     
    #exp(x::Real) = Symbolics.Term(exp,[x]) 
    #exp(x::Int64) = Symbolics.Term(exp,[x]) 
     
     
    data=readlines("julia_input.txt"); 
     
    number_failed = 0 
    for counter in 1:10 #length(data) 
       #println("processing line ",counter) 
       try 
          item = eval(Meta.parse(data[counter])) 
          print("\n\n****calling integrate(",item[2],",",item[3],")") 
          anti,n_unsolved,residual_error = integrate(item[2],item[3]) 
          println("anti=",anti) 
          println("n_unsolved=",n_unsolved) 
          println("residual_error=",residual_error) 
     
       catch 
          number_failed = number_failed + 1 
          #println(">>>>>>>>>error on integral ",counter) 
          println(">>>>>>>>>error on integral ",Meta.parse(data[counter])) 
       end 
    end 
     
    println("Failed to read ", number_failed, " integrals")
     
    

    This way I know which line has an error when reading the interals.

    Find why this error

    julia> (-x)^(1//2) 
    ERROR: DomainError with -1.0: 
    Exponentiation yielding a complex result requires a complex argument. 
    Replace x^y with (x+0im)^y, Complex(x)^y, or similar. 
    Stacktrace: 
     [1] throw_exp_domainerror(x::Float64) 
       @ Base.Math ./math.jl:37 
     [2] ^(x::Float64, y::Float64) 
       @ Base.Math ./math.jl:1003 
     [3] ^ 
       @ ./promotion.jl:422 [inlined] 
     [4] ^ 
       @ ./rational.jl:481 [inlined] 
     [5] unstable_pow 
       @ ~/.julia/packages/SymbolicUtils/qulQp/src/types.jl:801 [inlined] 
     [6] ^(a::SymbolicUtils.Mul{Number, Int64, Dict{Any, Number}, Nothing}, b::Rational{Int64}) 
       @ SymbolicUtils ~/.julia/packages/SymbolicUtils/qulQp/src/types.jl:1047 
     [7] top-level scope 
       @ REPL[32]:1
     
    

    But the integrate command currently only supports univariate expression with constant real or complex coefficients. So it can integrate \(2*x\) but can not integrate \(a*x\) so not possible to use it in CAS integration tests.

  2. to read symbolic expression from file see this post https://stackoverflow.com/questions/59543961/how-to-read-a-polynomial-from-a-text-file-in-julia