From 079fb86e988b21d83cbaa20f9ff822d1d913c2e6 Mon Sep 17 00:00:00 2001 From: Michael Schmischke Date: Wed, 20 Apr 2022 14:12:07 +0200 Subject: [PATCH] patch Grouped Transforms for Wavelets --- .github/workflows/ci.yml | 5 ++--- Project.toml | 4 ++-- src/ANOVAapprox.jl | 24 +++++++++++++++++++++--- src/analysis.jl | 36 ++++++++++++++++++------------------ src/approx.jl | 8 +++++++- src/errors.jl | 2 +- test/TestFunctionPeriodic.jl | 2 +- test/per_fista.jl | 2 +- test/per_lsqr.jl | 4 ++-- test/runtests.jl | 2 +- test/wav_lsqr.jl | 10 +++++----- 11 files changed, 61 insertions(+), 38 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 08ba5a3..ff9354a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - julia-version: [1.6] + julia-version: [1.7] os: [ubuntu-latest, windows-latest] steps: - uses: actions/checkout@v2 @@ -24,6 +24,5 @@ jobs: - uses: julia-actions/julia-processcoverage@v1 - uses: codecov/codecov-action@v2 with: - file: ./lcov.info name: codecov-umbrella - if: ${{ matrix.julia-version == '1.6' && matrix.os =='ubuntu-latest' }} + if: ${{ matrix.julia-version == '1.7' && matrix.os =='ubuntu-latest' }} diff --git a/Project.toml b/Project.toml index 5b7ee5b..0e422de 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "ANOVAapprox" uuid = "5e027bd6-ab01-4733-8320-e0223e929ebb" authors = ["Michael Schmischke and Felix Bartel "] -version = "1.1.5" +version = "1.1.6" [deps] Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" @@ -16,7 +16,7 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [compat] Aqua = "0.5" -GroupedTransforms = "1.1.2" +GroupedTransforms = "1.1.4" IterativeSolvers = "0.8, 0.9" LinearMaps = "3" SpecialFunctions = "1" diff --git a/src/ANOVAapprox.jl b/src/ANOVAapprox.jl index 11a13a0..3543edf 100644 --- a/src/ANOVAapprox.jl +++ b/src/ANOVAapprox.jl @@ -3,8 +3,17 @@ module ANOVAapprox using GroupedTransforms, LinearAlgebra, IterativeSolvers, LinearMaps, Distributed, SpecialFunctions -bases = ["per", "cos", "cheb", "std" ,"wav1", "wav2", "wav3", "wav4"] -types = Dict("per" => ComplexF64, "cos" => Float64, "cheb" => Float64, "std" => Float64, "wav1" => Float64, "wav2" => Float64,"wav3" => Float64,"wav4" => Float64) +bases = ["per", "cos", "cheb", "std", "wav1", "wav2", "wav3", "wav4"] +types = Dict( + "per" => ComplexF64, + "cos" => Float64, + "cheb" => Float64, + "std" => Float64, + "wav1" => Float64, + "wav2" => Float64, + "wav3" => Float64, + "wav4" => Float64, +) vtypes = Dict( "per" => Vector{ComplexF64}, "cos" => Vector{Float64}, @@ -15,7 +24,16 @@ vtypes = Dict( "wav3" => Vector{Float64}, "wav4" => Vector{Float64}, ) -gt_systems = Dict("per" => "exp", "cos" => "cos", "cheb" => "cos", "std" => "cos", "wav1" => "wav1", "wav2" => "wav2", "wav3" => "wav3", "wav4" => "wav4") +gt_systems = Dict( + "per" => "exp", + "cos" => "cos", + "cheb" => "cos", + "std" => "cos", + "wav1" => "wav1", + "wav2" => "wav2", + "wav3" => "wav3", + "wav4" => "wav4", +) function get_orderDependentBW(U::Vector{Vector{Int}}, N::Vector{Int})::Vector{Int} N_bw = zeros(Int64, length(U)) diff --git a/src/analysis.jl b/src/analysis.jl index 5a14fbe..1809284 100644 --- a/src/analysis.jl +++ b/src/analysis.jl @@ -9,13 +9,13 @@ function get_GSI( dict::Bool = false, )::Union{Vector{Float64},Dict{Vector{Int},Float64}} if a.basis == "wav1" - variances = norms(a.fc[λ],1,dict=false) .^ 2 + variances = norms(a.fc[λ], 1, dict = false) .^ 2 elseif a.basis == "wav2" - variances = norms(a.fc[λ],2,dict=false) .^ 2 + variances = norms(a.fc[λ], 2, dict = false) .^ 2 elseif a.basis == "wav3" - variances = norms(a.fc[λ],3,dict=false) .^ 2 + variances = norms(a.fc[λ], 3, dict = false) .^ 2 elseif a.basis == "wav4" - variances = norms(a.fc[λ],4,dict=false) .^ 2 + variances = norms(a.fc[λ], 4, dict = false) .^ 2 else variances = norms(a.fc[λ]) .^ 2 end @@ -25,18 +25,18 @@ function get_GSI( if dict gsis = Dict{Vector{Int},Float64}() if a.basis == "wav1" - variances = norms(a.fc[λ],1,dict=true) + variances = norms(a.fc[λ], 1, dict = true) elseif a.basis == "wav2" - variances = norms(a.fc[λ],2,dict=true) + variances = norms(a.fc[λ], 2, dict = true) elseif a.basis == "wav3" - variances = norms(a.fc[λ],3,dict=true) + variances = norms(a.fc[λ], 3, dict = true) elseif a.basis == "wav4" - variances = norms(a.fc[λ],4,dict=true) + variances = norms(a.fc[λ], 4, dict = true) else - variances = norms(a.fc[λ],dict = true) + variances = norms(a.fc[λ], dict = true) end - return Dict((u,variances[u]^2/variance_f) for u in keys(variances)) + return Dict((u, variances[u]^2 / variance_f) for u in keys(variances)) else return variances ./ variance_f @@ -64,7 +64,7 @@ function get_AttributeRanking(a::approx, λ::Float64)::Vector{Float64} d = size(a.X, 1) gsis = get_GSI(a, λ, dict = true) U = collect(keys(gsis)) - lengths = [ length(u) for u in U ] + lengths = [length(u) for u in U] ds = maximum(lengths) factors = zeros(Int64, d, ds) @@ -73,7 +73,7 @@ function get_AttributeRanking(a::approx, λ::Float64)::Vector{Float64} for j = 1:ds for v in U if (i in v) && (length(v) == j) - factors[i,j] += 1 + factors[i, j] += 1 end end end @@ -85,8 +85,8 @@ function get_AttributeRanking(a::approx, λ::Float64)::Vector{Float64} for u in U weights = 0.0 for s in u - r[s] += gsis[u] * 1/factors[s, length(u)] - weights += 1/factors[s, length(u)] + r[s] += gsis[u] * 1 / factors[s, length(u)] + weights += 1 / factors[s, length(u)] end nf += weights * gsis[u] end @@ -103,13 +103,13 @@ function get_AttributeRanking(a::approx)::Dict{Float64,Vector{Float64}} return Dict(λ => get_AttributeRanking(a, λ) for λ in collect(keys(a.fc))) end -function get_ActiveSet( a::approx, eps::Vector{Float64}, λ::Float64 )::Vector{Vector{Int}} +function get_ActiveSet(a::approx, eps::Vector{Float64}, λ::Float64)::Vector{Vector{Int}} U = a.U[2:end] - lengths = [ length(u) for u in U ] + lengths = [length(u) for u in U] ds = maximum(lengths) if length(eps) != ds - error( "Entries in vector eps have to be ds.") + error("Entries in vector eps have to be ds.") end gsi = get_GSI(a, λ) @@ -122,7 +122,7 @@ function get_ActiveSet( a::approx, eps::Vector{Float64}, λ::Float64 )::Vector{V end end - U_active = Vector{Vector{Int}}(undef, n+1) + U_active = Vector{Vector{Int}}(undef, n + 1) U_active[1] = [] idx = 2 diff --git a/src/approx.jl b/src/approx.jl index efce334..e0456cf 100644 --- a/src/approx.jl +++ b/src/approx.jl @@ -58,7 +58,13 @@ mutable struct approx bw = N end - if (basis == "per" || basis == "wav1" || basis == "wav2" || basis == "wav3" || basis == "wav4" ) && ((minimum(X) < -0.5) || (maximum(X) >= 0.5)) + if ( + basis == "per" || + basis == "wav1" || + basis == "wav2" || + basis == "wav3" || + basis == "wav4" + ) && ((minimum(X) < -0.5) || (maximum(X) >= 0.5)) error("Nodes need to be between -0.5 and 0.5.") elseif (basis == "cos") && ((minimum(X) < 0) || (maximum(X) > 1)) error("Nodes need to be between 0 and 1.") diff --git a/src/errors.jl b/src/errors.jl index 0244d9f..e9e85d9 100644 --- a/src/errors.jl +++ b/src/errors.jl @@ -145,7 +145,7 @@ end This function computes the relative ``L_2`` error of the function given the norm `norm` and a function that returns the basis coefficients `bc_fun` for regularization parameter `λ`. """ function get_L2error(a::approx, norm::Float64, bc_fun::Function, λ::Float64)::Float64 - if a.basis=="per" || a.basis == "cos" || a.basis =="cheb"|| a.basis == "std" + if a.basis == "per" || a.basis == "cos" || a.basis == "cheb" || a.basis == "std" error = norm^2 index_set = get_IndexSet(a.trafo.setting, size(a.X, 1)) diff --git a/test/TestFunctionPeriodic.jl b/test/TestFunctionPeriodic.jl index da23679..e7339fb 100644 --- a/test/TestFunctionPeriodic.jl +++ b/test/TestFunctionPeriodic.jl @@ -85,7 +85,7 @@ function f(x::Vector{Float64})::Float64 error("Argument has to be 6-dimensional") end - if !isempty(x[(x.>0.5).|(x.<-.5)]) + if !isempty(x[(x.>0.5).|(x.<-0.5)]) error("The nodes have to be between -0.5 and 0.5.") end diff --git a/test/per_fista.jl b/test/per_fista.jl index 7b38e5b..050a663 100644 --- a/test/per_fista.jl +++ b/test/per_fista.jl @@ -16,7 +16,7 @@ y_test = [TestFunctionPeriodic.f(X_test[:, i]) for i = 1:M] ads = ANOVAapprox.approx(X, complex(y), ds, bw, "per") ANOVAapprox.approximate(ads, lambda = λs, solver = "fista") -ANOVAapprox.get_ActiveSet(ads, [0.05,0.05]) +ANOVAapprox.get_ActiveSet(ads, [0.05, 0.05]) bw = ANOVAapprox.get_orderDependentBW(TestFunctionPeriodic.AS, [128, 32]) aU = ANOVAapprox.approx(X, complex(y), TestFunctionPeriodic.AS, bw, "per") diff --git a/test/per_lsqr.jl b/test/per_lsqr.jl index d83ca10..bd473f1 100644 --- a/test/per_lsqr.jl +++ b/test/per_lsqr.jl @@ -17,8 +17,8 @@ y_test = [TestFunctionPeriodic.f(X_test[:, i]) for i = 1:M] ads = ANOVAapprox.approx(X, complex(y), ds, bw, "per") ANOVAapprox.approximate(ads, lambda = λs) -println( "AR: ", sum(ANOVAapprox.get_AttributeRanking(ads, 0.0)) ) -@test abs( sum(ANOVAapprox.get_AttributeRanking(ads, 0.0)) - 1 ) < 0.0001 +println("AR: ", sum(ANOVAapprox.get_AttributeRanking(ads, 0.0))) +@test abs(sum(ANOVAapprox.get_AttributeRanking(ads, 0.0)) - 1) < 0.0001 bw = ANOVAapprox.get_orderDependentBW(TestFunctionPeriodic.AS, [128, 32]) diff --git a/test/runtests.jl b/test/runtests.jl index 2d980dc..c3fde3d 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -16,7 +16,7 @@ using .TestFunctionCheb rng = MersenneTwister(1234) -tests = ["misc", "cheb_fista", "cheb_lsqr", "per_lsqr", "per_fista","wav_lsqr"] +tests = ["misc", "cheb_fista", "cheb_lsqr", "per_lsqr", "per_fista", "wav_lsqr"] #tests = ["misc", "cheb_lsqr", "per_lsqr", "per_fista"] for t in tests diff --git a/test/wav_lsqr.jl b/test/wav_lsqr.jl index 0588416..e06e668 100644 --- a/test/wav_lsqr.jl +++ b/test/wav_lsqr.jl @@ -9,11 +9,11 @@ d = 6 ds = 2 M = 10_000 max_iter = 50 -bw = [4,4] +bw = [4, 4] λs = [0.0, 1.0] -X = rand( d, M) .- 0.5 +X = rand(d, M) .- 0.5 y = [TestFunctionPeriodic.f(X[:, i]) for i = 1:M] X_test = rand(d, M) .- 0.5 y_test = [TestFunctionPeriodic.f(X_test[:, i]) for i = 1:M] @@ -23,10 +23,10 @@ y_test = [TestFunctionPeriodic.f(X_test[:, i]) for i = 1:M] ads = ANOVAapprox.approx(X, y, ds, bw, "wav2") ANOVAapprox.approximate(ads, lambda = λs) -println( "AR: ", sum(ANOVAapprox.get_AttributeRanking(ads, 0.0)) ) -@test abs( sum(ANOVAapprox.get_AttributeRanking(ads, 0.0)) - 1 ) < 0.0001 +println("AR: ", sum(ANOVAapprox.get_AttributeRanking(ads, 0.0))) +@test abs(sum(ANOVAapprox.get_AttributeRanking(ads, 0.0)) - 1) < 0.0001 -bw = ANOVAapprox.get_orderDependentBW(TestFunctionPeriodic.AS, [4,4]) +bw = ANOVAapprox.get_orderDependentBW(TestFunctionPeriodic.AS, [4, 4]) aU = ANOVAapprox.approx(X, y, TestFunctionPeriodic.AS, bw, "wav2") ANOVAapprox.approximate(aU, lambda = λs)