From 296678b2f86f2dbe67431c011f2aaa958757ba2a Mon Sep 17 00:00:00 2001 From: Arno Strouwen Date: Sat, 30 Dec 2023 16:20:15 +0100 Subject: [PATCH] Aqua + typos CI add begin end around Aqua tests a --- .github/workflows/Downgrade.yml | 2 +- .github/workflows/SpellCheck.yml | 13 +++++++++ .typos.toml | 2 ++ Project.toml | 11 +++++--- src/integral.jl | 2 -- src/sparse.jl | 10 +++---- src/symbolic.jl | 46 ++++++++++++++++---------------- test/qa.jl | 11 ++++++++ test/runtests.jl | 2 ++ 9 files changed, 64 insertions(+), 35 deletions(-) create mode 100644 .github/workflows/SpellCheck.yml create mode 100644 .typos.toml create mode 100644 test/qa.jl diff --git a/.github/workflows/Downgrade.yml b/.github/workflows/Downgrade.yml index cbcc6ac..372644a 100644 --- a/.github/workflows/Downgrade.yml +++ b/.github/workflows/Downgrade.yml @@ -7,7 +7,7 @@ on: - 'docs/**' push: branches: - - master + - main paths-ignore: - 'docs/**' jobs: diff --git a/.github/workflows/SpellCheck.yml b/.github/workflows/SpellCheck.yml new file mode 100644 index 0000000..599253c --- /dev/null +++ b/.github/workflows/SpellCheck.yml @@ -0,0 +1,13 @@ +name: Spell Check + +on: [pull_request] + +jobs: + typos-check: + name: Spell Check with Typos + runs-on: ubuntu-latest + steps: + - name: Checkout Actions Repository + uses: actions/checkout@v3 + - name: Check spelling + uses: crate-ci/typos@v1.16.23 \ No newline at end of file diff --git a/.typos.toml b/.typos.toml new file mode 100644 index 0000000..e2b3e6f --- /dev/null +++ b/.typos.toml @@ -0,0 +1,2 @@ +[default.extend-words] +numer = "numer" \ No newline at end of file diff --git a/Project.toml b/Project.toml index aecbe7d..8e7e25e 100644 --- a/Project.toml +++ b/Project.toml @@ -14,18 +14,21 @@ SymbolicUtils = "d1185830-fcd6-423d-90d6-eec64667417b" Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" [compat] +Aqua = "0.8" DataDrivenDiffEq = "1.3" DataDrivenSparse = "0.1.2" DataStructures = "0.18.13" +LinearAlgebra = "1.10" SpecialFunctions = "2" -Statistics = "1.9" +Statistics = "1.10" SymbolicUtils = "1.4" Symbolics = "5.12" -julia = "1.9" -LinearAlgebra = "<0.0.1, 1" +Test = "1" +julia = "1.10" [extras] +Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["Test"] +test = ["Aqua", "Test"] diff --git a/src/integral.jl b/src/integral.jl index 9171472..931928c 100644 --- a/src/integral.jl +++ b/src/integral.jl @@ -1,8 +1,6 @@ using LinearAlgebra using Statistics: mean, std -Base.signbit(z::Complex{T}) where {T <: Number} = signbit(real(z)) -Base.signbit(x::SymbolicUtils.Sym{Number}) = false """ integrate(eq, x; kwargs...) diff --git a/src/sparse.jl b/src/sparse.jl index ae65596..764d69e 100644 --- a/src/sparse.jl +++ b/src/sparse.jl @@ -52,9 +52,9 @@ function prune_basis(eq, x, basis; plan = default_plan()) return basis[l] end -# init_basis_matrix tranforms the integration problem into a linear system -# -# It returns A, X, V, where +# init_basis_matrix transforms the integration problem into a linear system +# +# It returns A, X, V, where # # A: the normalized training matrix, we seek a vector q such that A * q = 1 # X: a vector of complex test points @@ -217,14 +217,14 @@ function hints(eq, x, basis; plan = default_plan()) return h, ε catch e - # println("Error from hints: ", e) + # println("Error from hints: ", e) end return 0, Inf end # best_hints works is the link between numerical and symbolic integration. -# It convers a symbolic integrad eq into a univariate expression, performs +# It converts a symbolic integrad eq into a univariate expression, performs # symbolic-numeric integration, and the returns a list of symbolic ansatzes # corresponding to the solution function best_hints(eq, x, basis; plan = default_plan(), num_trials = 10) diff --git a/src/symbolic.jl b/src/symbolic.jl index 2672887..853ef20 100644 --- a/src/symbolic.jl +++ b/src/symbolic.jl @@ -1,6 +1,6 @@ ########################### Utility functions ######################### -# beautify convers floats to integers/rational numbers with small +# beautify converts floats to integers/rational numbers with small # denominators if possible function beautify(eq) if is_add(eq) @@ -47,22 +47,22 @@ function split_terms(eq, x) end end -# is_holonomic checks whether y is a holonomic function, i.e., +# is_holonomic checks whether y is a holonomic function, i.e., # is closed under differentiation w.r.t. x -# +# # For our purpose, we define a holonomic function as one composed # of the positive powers of x, sin, cos, exp, sinh, and cosh -# +# # Args: # y: the expression to check for holonomy # x: independent variable -# +# # Returns: # true if y is holonomic function is_holonomic(y, x) y = value(y) - # technically, polynomials are not holonomic, but + # technically, polynomials are not holonomic, but # practically we can include them if is_polynomial(y, x) return true @@ -90,8 +90,8 @@ function is_holonomic(y, x) return false end -# blender generates a list of ansatzes based on repetative -# differentiation. It works for holonomic functions, which +# blender generates a list of ansatzes based on repetitive +# differentiation. It works for holonomic functions, which # are closed under differentiation. function blender(y, x; n = 3) basis = value(y) @@ -111,7 +111,7 @@ function blender(y, x; n = 3) return split_terms(basis, x) end -# subs_symbols returns a dictionary of the symbolic constants +# subs_symbols returns a dictionary of the symbolic constants # in the expression and random real value assignments. # # Args: @@ -138,8 +138,8 @@ function subs_symbols(eq, x; include_x = false, radius = 5.0, as_complex = true) return S end -# atomize splits terms into a part dependent on x and a part -# constant w.r.t. variables in xs. +# atomize splits terms into a part dependent on x and a part +# constant w.r.t. variables in xs. # # For example, `atomize(a*sin(b*x), x)` is `(a, sin(b*x))`) function atomize(eq, xs...) @@ -165,7 +165,7 @@ function atomize(eq, xs...) end end -# apply_coefs generates the final integral based on the list +# apply_coefs generates the final integral based on the list # of coefficients (q) and a list of ansatzes (ker). function apply_coefs(q, ker) s = 0 @@ -201,11 +201,11 @@ complex_from_num(x) = Complex(value(real(x)), value(imag(x))) ########################### Symbolic Integration ############################# # integrate_symbolic is the main entry point for symbolic integration. -# +# # Argu: # eq: the expression to integrate # x: independent variable -# +# # Returns: # the integral or nothing if no solution function integrate_symbolic(eq, x; plan = default_plan()) @@ -226,10 +226,10 @@ struct Problem x::Expression # independent variable coef::Expression # coefficient of the integrand ker::Array{Expression} # the pruned list of the basis expressions (kernel) - plan::NumericalPlan # the numerial plan, containing various parameters + plan::NumericalPlan # the numerical plan, containing various parameters end -# Constructor to create a Problem for integrand eq +# Constructor to create a Problem for integrand eq function Problem(eq, x; plan = default_plan()) eq = expand(eq) coef, eq = atomize(eq, x) @@ -314,14 +314,14 @@ subs_symbols(prob::Problem) = subs_symbols(prob.eq, prob.x) abstract type IntegrationAlgorithm end struct SymbolicIntegrator <: IntegrationAlgorithm - eqs::Vector{Equation} # list of equations of the form Σ θ[i]*frag[i] ~ 0 + eqs::Vector{Equation} # list of equations of the form Σ θ[i]*frag[i] ~ 0 vars::Vector{Expression} # list of dummy variables (θ[1], θ[2], ...) frags::Dict # Dict of fragments of form frag => expression in θs end @variables θ[1:30] -# Constructor creating a SymbolicIntegrator algorithm +# Constructor creating a SymbolicIntegrator algorithm # from an integration Problem function SymbolicIntegrator(prob::Problem) frags = Dict() @@ -355,16 +355,16 @@ function solver(prob::Problem, alg::SymbolicIntegrator) sol = apply_coefs(q, prob.ker) return sol catch e - # println(e) + # println(e) end return nothing end # If the linear system generated by the SymbolicIntegrator solver is -# under-determined, make_square uses semi-numerical methods to +# under-determined, make_square uses semi-numerical methods to # generate a full-rank linear system. -# +# # The output is another SymbolicIntegrator or nothing if unsuccessful. function make_square(prob::Problem, alg::SymbolicIntegrator) n = length(alg.vars) @@ -390,10 +390,10 @@ function make_square(prob::Problem, alg::SymbolicIntegrator) end struct NumericIntegrator - A::AbstractMatrix # training dataset as a normalized linear system + A::AbstractMatrix # training dataset as a normalized linear system X::AbstractVector # vector of test points V::AbstractMatrix # verification dataset - basis::Vector{Expression} # expand basis + basis::Vector{Expression} # expand basis end # Constructor to create a NumericIntegrator algorithm from prob diff --git a/test/qa.jl b/test/qa.jl new file mode 100644 index 0000000..8d6ac5d --- /dev/null +++ b/test/qa.jl @@ -0,0 +1,11 @@ +using SymbolicNumericIntegration, Aqua +@testset "Aqua" begin + Aqua.find_persistent_tasks_deps(SymbolicNumericIntegration) + Aqua.test_ambiguities(SymbolicNumericIntegration, recursive = false) + Aqua.test_deps_compat(SymbolicNumericIntegration) + Aqua.test_piracies(SymbolicNumericIntegration, broken = true) + Aqua.test_project_extras(SymbolicNumericIntegration) + Aqua.test_stale_deps(SymbolicNumericIntegration) + Aqua.test_unbound_args(SymbolicNumericIntegration) + Aqua.test_undefined_exports(SymbolicNumericIntegration) +end diff --git a/test/runtests.jl b/test/runtests.jl index a61504f..35d61e5 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -7,6 +7,8 @@ using SymbolicUtils.Rewriters using Test +@testset "Quality Assurance" begin include("qa.jl") end + include("axiom.jl") ##############################################################################