Mon, 06 Dec 2021 11:52:10 +0200
Split FunctionalProgramming.jl, VectorMath.jl, and ThreadUtil.jl out of Util.jl.
src/AlgTools.jl | file | annotate | diff | comparison | revisions | |
src/FunctionalProgramming.jl | file | annotate | diff | comparison | revisions | |
src/ThreadUtil.jl | file | annotate | diff | comparison | revisions | |
src/Util.jl | file | annotate | diff | comparison | revisions | |
src/VectorMath.jl | file | annotate | diff | comparison | revisions |
--- a/src/AlgTools.jl Wed Dec 15 10:35:57 2021 +0200 +++ b/src/AlgTools.jl Mon Dec 06 11:52:10 2021 +0200 @@ -1,12 +1,31 @@ __precompile__() +""" + +`module AlgTools` + +This module has the submodules: +- `FunctionalProgramming` +- `StructTools` +- `LinkedLists` +- `Logger` +- `Iterate` +- `VectorMath` +- `Util` +- `ThreadUtil` +- `Comms` +- `LinOps` +- `DifferentiableFN` +""" module AlgTools include("StructTools.jl") include("LinkedLists.jl") include("Iterate.jl") +include("VectorMath.jl") include("Util.jl") +include("ThreadUtil.jl") include("Comms.jl") include("LinOps.jl") include("DifferentiableFN.jl")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/FunctionalProgramming.jl Mon Dec 06 11:52:10 2021 +0200 @@ -0,0 +1,60 @@ +################################### +# Tools for functional programming +################################### + +""" + +`module AlgTools.FunctionalProgramming` + +This module implements: +- `curry` +- `curryflip` +""" +module FunctionalProgramming + +############## +# Our exports +############## + +export curry, + curryflip + +########### +# Currying +########### + +""" +`curry(f)` and `curry(f, x)` + +From a function `f` of parameters `(x, y...; kwargs...)` construct a function `g` +of parameter `x`, returning a function of parameter `(y...; kwargs...)`. + +The version with parameter `x` already applies the first argument, returning a function +of `(y...; kwargs...)`. +""" +function curry(f::Function) + return x -> (y...; kwargs...)-> f(x, y...; kwargs...) +end + +function curry(f::Function, x) + return (y...; kwargs...)-> f(x, y...; kwargs...) +end + +""" +`curryflip(f)` and `curryflip(f, y...; kwargs...) + +From a function `f` of parameters `(x, y...; kwargs...)` construct a function `g` +of parameter `(y...; kargs...)`, returning a function of parameter `x` + +The version with parametesr `(y...; kwargs...)` already applies these parameters, +returning a function of `x`. +""" +function curryflip(f::Function) + return (y...; kwargs...) -> x -> f(x, y...; kwargs...) +end + +function curryflip(f::Function, y...; kwargs...) + return x ->f(x, y...; kwargs...) +end + +end # module
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ThreadUtil.jl Mon Dec 06 11:52:10 2021 +0200 @@ -0,0 +1,46 @@ +########################### +# Some threading utilities +########################### + +__precompile__() + +module ThreadUtil + +############## +# Our exports +############## + +export @threadsif, + @background, + @backgroundif + + +########## +# Threads +########## + +macro threadsif(threads, loop) + return esc(:(if $threads + Threads.@threads $loop + else + $loop + end)) +end + +macro background(bgtask, fgtask) + return :(t = Threads.@spawn $(esc(bgtask)); + $(esc(fgtask)); + wait(t)) +end + +macro backgroundif(threads, bgtask, fgtask) + return :(if $(esc(threads)) + @background $(esc(bgtask)) $(esc(fgtask)) + else + $(esc(bgtask)) + $(esc(fgtask)) + end) +end + +end # Module +
--- a/src/Util.jl Wed Dec 15 10:35:57 2021 +0200 +++ b/src/Util.jl Mon Dec 06 11:52:10 2021 +0200 @@ -12,57 +12,7 @@ export map_first_slice!, reduce_first_slice, - norm₁, - norm₂, - γnorm₂, - norm₂w, - norm₂², - norm₂w², - norm₂₁, - γnorm₂₁, - dot, - mean, - proj_norm₂₁ball!, - proj_nonneg!, - curry, - ⬿, - @threadsif, - @background, - @backgroundif - - -########## -# Threads -########## - -macro threadsif(threads, loop) - return esc(:(if $threads - Threads.@threads $loop - else - $loop - end)) -end - -macro background(bgtask, fgtask) - return :(t = Threads.@spawn $(esc(bgtask)); - $(esc(fgtask)); - wait(t)) -end - -macro backgroundif(threads, bgtask, fgtask) - return :(if $(esc(threads)) - @background $(esc(bgtask)) $(esc(fgtask)) - else - $(esc(bgtask)) - $(esc(fgtask)) - end) -end - -######################## -# Functional programming -######################### - -curry = (f::Function,y...)->(z...)->f(y...,z...) + ⬿ ############################### # For working with NamedTuples @@ -94,121 +44,5 @@ return accum end -########################### -# Norms and inner products -########################### - -@inline function dot(x, y) - @assert(length(x)==length(y)) - - accum=0 - for i=1:length(y) - @inbounds accum += x[i]*y[i] - end - return accum -end - -@inline function norm₂w²(y, w) - #Insane memory allocs - #return @inbounds sum(i -> y[i]*y[i]*w[i], 1:length(y)) - accum=0 - for i=1:length(y) - @inbounds accum=accum+y[i]*y[i]*w[i] - end - return accum -end - -@inline function norm₂w(y, w) - return √(norm₂w²(y, w)) -end - -@inline function norm₂²(y) - #Insane memory allocs - #return @inbounds sum(i -> y[i]*y[i], 1:length(y)) - accum=0 - for i=1:length(y) - @inbounds accum=accum+y[i]*y[i] - end - return accum -end - -@inline function norm₂(y) - return √(norm₂²(y)) -end - -@inline function norm₁(y) - accum=0 - for i=1:length(y) - @inbounds accum=accum+abs(y[i]) - end - return accum -end - -@inline function γnorm₂(y, γ) - hubersq = xsq -> begin - x=√xsq - return if x > γ - x-γ/2 - elseif x<-γ - -x-γ/2 - else - xsq/(2γ) - end - end - - if γ==0 - return norm₂(y) - else - return hubersq(norm₂²(y)) - end -end - -function norm₂₁(y) - return reduce_first_slice((s, x) -> s+norm₂(x), y) -end - -function γnorm₂₁(y,γ) - return reduce_first_slice((s, x) -> s+γnorm₂(x, γ), y) -end - -function mean(v) - return sum(v)/prod(size(v)) -end - -@inline function proj_norm₂₁ball!(y, α) - α²=α*α - - if ndims(y)==3 && size(y, 1)==2 - @inbounds for i=1:size(y, 2) - @simd for j=1:size(y, 3) - n² = y[1,i,j]*y[1,i,j]+y[2,i,j]*y[2,i,j] - if n²>α² - v = α/√n² - y[1, i, j] *= v - y[2, i, j] *= v - end - end - end - else - y′=reshape(y, (size(y, 1), prod(size(y)[2:end]))) - - @inbounds @simd for i=1:size(y′, 2)# in CartesianIndices(size(y)[2:end]) - n² = norm₂²(@view(y′[:, i])) - if n²>α² - @views y′[:, i] .*= (α/√n²) - end - end - end -end - -@inline function proj_nonneg!(y) - @inbounds @simd for i=1:length(y) - if y[i] < 0 - y[i] = 0 - end - end - return y -end - end # Module
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/VectorMath.jl Mon Dec 06 11:52:10 2021 +0200 @@ -0,0 +1,147 @@ +########################### +# Norms, projections, etc. +########################### + +__precompile__() + +module VectorMath + +############## +# Our exports +############## + +export norm₁, + norm₂, + γnorm₂, + norm₂w, + norm₂², + norm₂w², + norm₂₁, + γnorm₂₁, + dot, + mean, + proj_norm₂₁ball!, + proj_nonneg! + +########################### +# Norms and inner products +########################### + +@inline function dot(x, y) + @assert(length(x)==length(y)) + + accum=0 + for i=1:length(y) + @inbounds accum += x[i]*y[i] + end + return accum +end + +@inline function norm₂w²(y, w) + #Insane memory allocs + #return @inbounds sum(i -> y[i]*y[i]*w[i], 1:length(y)) + accum=0 + for i=1:length(y) + @inbounds accum=accum+y[i]*y[i]*w[i] + end + return accum +end + +@inline function norm₂w(y, w) + return √(norm₂w²(y, w)) +end + +@inline function norm₂²(y) + #Insane memory allocs + #return @inbounds sum(i -> y[i]*y[i], 1:length(y)) + accum=0 + for i=1:length(y) + @inbounds accum=accum+y[i]*y[i] + end + return accum +end + +@inline function norm₂(y) + return √(norm₂²(y)) +end + +@inline function norm₁(y) + accum=0 + for i=1:length(y) + @inbounds accum=accum+abs(y[i]) + end + return accum +end + +@inline function γnorm₂(y, γ) + hubersq = xsq -> begin + x=√xsq + return if x > γ + x-γ/2 + elseif x<-γ + -x-γ/2 + else + xsq/(2γ) + end + end + + if γ==0 + return norm₂(y) + else + return hubersq(norm₂²(y)) + end +end + +function norm₂₁(y) + return reduce_first_slice((s, x) -> s+norm₂(x), y) +end + +function γnorm₂₁(y,γ) + return reduce_first_slice((s, x) -> s+γnorm₂(x, γ), y) +end + +function mean(v) + return sum(v)/prod(size(v)) +end + +############## +# Projections +############## + +@inline function proj_norm₂₁ball!(y, α) + α²=α*α + + if ndims(y)==3 && size(y, 1)==2 + @inbounds for i=1:size(y, 2) + @simd for j=1:size(y, 3) + n² = y[1,i,j]*y[1,i,j]+y[2,i,j]*y[2,i,j] + if n²>α² + v = α/√n² + y[1, i, j] *= v + y[2, i, j] *= v + end + end + end + else + y′=reshape(y, (size(y, 1), prod(size(y)[2:end]))) + + @inbounds @simd for i=1:size(y′, 2)# in CartesianIndices(size(y)[2:end]) + n² = norm₂²(@view(y′[:, i])) + if n²>α² + @views y′[:, i] .*= (α/√n²) + end + end + end +end + +@inline function proj_nonneg!(y) + @inbounds @simd for i=1:length(y) + if y[i] < 0 + y[i] = 0 + end + end + return y +end + +end # Module +