Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
a99102e
test
jason-yoon21 Dec 6, 2025
9e1dab4
cicd fix
jason-yoon21 Dec 6, 2025
5d22063
test
jason-yoon21 Dec 6, 2025
f3fd3f6
cicd fix
jason-yoon21 Dec 6, 2025
9a8f2a3
Merge branch 'jyoon/documenter_teset' of https://github.com/UCD4IDS/p…
jason-yoon21 Dec 6, 2025
ceb0573
add extras
jason-yoon21 Dec 6, 2025
6cc9864
fftw
jason-yoon21 Dec 6, 2025
b32304e
Merge branch 'main' into jyoon/documenter_teset
jason-yoon21 Dec 6, 2025
c281969
fftw
jason-yoon21 Dec 6, 2025
feaedd3
Merge branch 'jyoon/documenter_teset' of https://github.com/UCD4IDS/p…
jason-yoon21 Dec 6, 2025
a0f774e
test update
jason-yoon21 Dec 6, 2025
504ff5f
add aarch64
jason-yoon21 Dec 6, 2025
865e11e
arch
jason-yoon21 Dec 6, 2025
e47ff4a
name fix
jason-yoon21 Dec 6, 2025
40deba3
exclude aarch64 windows
jason-yoon21 Dec 6, 2025
9401219
update resolve
jason-yoon21 Dec 6, 2025
559c825
remove aarch64
jason-yoon21 Dec 6, 2025
75c5dd4
updates
jason-yoon21 Jan 4, 2026
68dd4fa
Merge branch 'jyoon/documenter_teset' into jyoon/refactor_1
jason-yoon21 Jan 4, 2026
c5bbeed
test for 1.11 and 1.12 macos
jason-yoon21 Jan 4, 2026
e9830b0
test
jason-yoon21 Jan 4, 2026
2837e04
documenter
jason-yoon21 Jan 17, 2026
2cd6b7d
documenter
jason-yoon21 Jan 17, 2026
bd53a7b
test
jason-yoon21 Jan 21, 2026
e8ba9a8
docs make jl
jason-yoon21 Jan 30, 2026
6779209
fix doc action
jason-yoon21 Jan 30, 2026
fcf1f4d
doc github action fix
jason-yoon21 Jan 30, 2026
81290c5
docs github action
jason-yoon21 Jan 30, 2026
ca4034d
docs github action fix
jason-yoon21 Jan 30, 2026
da78196
docs github action
jason-yoon21 Jan 30, 2026
c92b853
test
jason-yoon21 Jan 30, 2026
e5b6c8f
test
jason-yoon21 Jan 30, 2026
639993b
fix
jason-yoon21 Jan 30, 2026
f45de48
test
jason-yoon21 Jan 30, 2026
30b06db
version up
jason-yoon21 Jan 30, 2026
ae42e74
version up
jason-yoon21 Jan 30, 2026
e01acc5
test
jason-yoon21 Jan 30, 2026
e3eda44
test
jason-yoon21 Jan 30, 2026
4c41bd7
test
jason-yoon21 Jan 30, 2026
8092010
doc cdci
jason-yoon21 Feb 8, 2026
007aa90
doc cdci
jason-yoon21 Feb 8, 2026
6aeeec1
test
jason-yoon21 Feb 8, 2026
dedae71
test
jason-yoon21 Feb 8, 2026
ef1c239
test
jason-yoon21 Feb 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,21 @@ on:
- Project.toml
jobs:
test:
name: Julia ${{ matrix.julia-version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }}
name: Julia ${{ matrix.julia-version }} - ${{ matrix.os }} - ${{ matrix.julia-arch }} - ${{ github.event_name }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [windows-latest, macos-latest]
julia-version: ['1.10', 'lts']
arch:
- x64
julia-arch: [x64]
julia-version: ['1.10','1.11','1.12', 'lts']

steps:
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@v2
with:
version: ${{ matrix.julia-version }}
arch: ${{ matrix.arch }}
arch: ${{ matrix.julia-arch }}
- uses: actions/cache@v4
env:
cache-name: cache-artifacts
Expand All @@ -45,7 +45,7 @@ jobs:
${{ runner.os }}-
- uses: julia-actions/julia-buildpkg@v1
- name: Resolve/Update dependencies
run: julia -e 'using Pkg; Pkg.resolve()' # Or Pkg.update()
run: julia -e 'using Pkg; Pkg.activate("."); Pkg.instantiate(); Pkg.update();' # Or Pkg.update()
- uses: julia-actions/julia-runtest@v1
with:
annotate: true
Expand Down
27 changes: 27 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Docs

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@latest
with:
version: '1.12'
- name: Install project environment
run: |
echo "GITHUB_WORKSPACE=$GITHUB_WORKSPACE"
julia --project="${{ github.workspace }}" -e 'using Pkg; Pkg.instantiate(); Pkg.precompile()'
- name: Build documentation
run: julia --project=. docs/make.jl
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs/build
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@
test/.ipynb_checkpoints
test/*.ipynb
Manifest.toml
Manifest-v1.11.toml
Manifest-v1.11.toml
*.txt
docs/build/
18 changes: 11 additions & 7 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ uuid = "c853eca7-4467-4dac-871a-88cef1644acc"
version = "1.0.0"
authors = []

[workspace]
projects = ["test", "docs"]

[deps]
AbstractFFTs = "621f4979-c628-5d54-868e-fcf4e3e8185c"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341"
FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
ImageIO = "82e4d734-157c-48bb-816b-45c225c6df19"
Expand All @@ -17,24 +21,24 @@ Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[weakdeps]
AbstractFFTs = "621f4979-c628-5d54-868e-fcf4e3e8185c"
FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" # UUID for the standard library Test
AbstractFFTs = "621f4979-c628-5d54-868e-fcf4e3e8185c"

[compat]
AbstractFFTs = "1"
Documenter = "1.16.1"
FFTW = "1"
FileIO = "1"
ImageIO = "0.6"
ImageMagick = "1"
Images = "0.26"
MAT = "0.10, 0.11"
MAT = "0.10"
Plots = "1"
Statistics = "1"

[extras]
AbstractFFTs = "621f4979-c628-5d54-868e-fcf4e3e8185c"
FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test", "FFTW", "AbstractFFTs"]
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,31 @@ iphlct = iphlct2d(phlct, n)

Reference: [Professor Saito's paper][paper] page 30 Chapter 6.2.2.

## Examples

Basic DST/IDST round-trip:

```julia
using .PolyHarmonicTrigTransforms

x = randn(8)
y = dst(x)
x_rec = idst(y)
@assert maximum(abs.(x_rec - 4 .* x ./ 4)) < 1e-12 # numeric check
```

PHLCT forward/backward round-trip (block size `N`):

```julia
using .PolyHarmonicTrigTransforms

n = 8
img = randn(n, n)
coeffs = phlct_forward(img, n)
img_rec = phlct_backward(coeffs, n)
@assert norm(img - img_rec) / norm(img) < 1e-12
```

#### Image Testing

To test images, first take your chosen image and convert it into a square image (i.e. size n x n where n is the new size of the image after using tools to square it).
Expand Down
9 changes: 9 additions & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name = "PolyHarmonicTrigTransformsDocs"
uuid = "00000000-0000-0000-0000-000000000001"
authors = ["UCD4IDS"]

[deps]
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"

[compat]
Documenter = "1.16.1"
17 changes: 17 additions & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Documenter
using PolyHarmonicTrigTransforms

makedocs(
modules = [PolyHarmonicTrigTransforms],
sitename = "PolyHarmonicTrigTransforms.jl",
pages = [
"Home" => "index.md",
"API" => "api.md",
],
format = Documenter.HTML(),
clean = true,
debug = true,
checkdocs = :none, # disable docstring checks to avoid failing on undocumented symbols
)

println("Documentation built: $(joinpath(@__DIR__, "build"))")
8 changes: 8 additions & 0 deletions docs/src/api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# API Reference

This page documents the package API automatically.

```@autodocs
Modules = [PolyHarmonicTrigTransforms]
Order = [:modules, :types, :functions]
```
15 changes: 15 additions & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# PolyHarmonicTrigTransforms

Short overview: polyharmonic and trigonometric transform utilities for signal and image processing.

## Quick start

```julia
using PolyHarmonicTrigTransforms
using Random

v = rand(8)
dst(v)
```

See the API reference generated from docstrings for detailed usage of `dst`, `idst`, `llst2d`, and other exported functions.
66 changes: 63 additions & 3 deletions src/dst.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,83 @@
# See also: IDST

module DST
using AbstractFFTs, FFTW
function _ensure_fftw()
if !isdefined(@__MODULE__, :FFTW)
Core.eval(Main, :(using FFTW))
Core.eval(@__MODULE__, :(const FFTW = Main.FFTW))
end
return nothing
end

export dst, dst_old
export dst, dst!, dst_u, plan_dst, dst_old

"""
dst(x; dims=1)

Compute the Type-I Discrete Sine Transform (DST) of `x` along `dims`.

Arguments
- `x`: an `AbstractArray` (vector or matrix).
- `dims`: dimension to transform (default `1`).

Returns
- transformed array of the same shape as `x`.

Example
```julia
y = dst([1.0,2.0,3.0])
```
"""
function dst(x::AbstractArray, dims=1)
_ensure_fftw()
N = size(x, dims)
return FFTW.r2r(x, FFTW.RODFT00, dims) / 2
end

function dst_u(x::AbstractArray, dims=1)
_ensure_fftw()
N = size(x, dims)
new_x = FFTW.r2r(x, FFTW.RODFT00, dims)

return new_x / (sqrt(2*N)) #unitory value
end

"""
plan_dst(x; dims=1, flags=FFTW.MEASURE)

Create an FFTW r2r plan for the DST (RODFT00) on `x`. The returned plan
can be executed with `plan * x`.
"""
function plan_dst(x::AbstractArray; dims=1, flags=FFTW.MEASURE)
_ensure_fftw()
return FFTW.r2r_plan(x, FFTW.RODFT00, dims; flags=flags)
end

"""
dst!(x; dims=1)

In-place DST that overwrites `x` with its transform when possible. Falls
back to a safe out-of-place compute and copy if the in-place routine is
not available on the current platform.
"""
function dst!(x::AbstractArray; dims=1)
_ensure_fftw()
try
# Try to use FFTW in-place r2r if available
FFTW.r2r!(x, FFTW.RODFT00, dims)
x .*= 0.5
return x
catch _
# Fallback: compute out-of-place and copy into x
tmp = FFTW.r2r(x, FFTW.RODFT00, dims)
tmp .*= 0.5
x .= tmp
return x
end
end

function dst_old(a::AbstractArray, n=nothing)
_ensure_fftw()
if minimum(size(a)) == 1
if size(a, 2) > 1
do_trans = 1
Expand All @@ -73,7 +133,7 @@ module DST
y = zeros(2 * (n + 1), m)
y[2:n+1, :] = aa
y[n+3:2*(n+1), :] = -reverse(aa, dims=1)
yy = fft(y, (1,))
yy = FFTW.fft(y, (1,))
b = yy[2:n+1, :] / (-2 * sqrt(-1 + 0im))


Expand Down
18 changes: 18 additions & 0 deletions src/helper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ module HELPER

export drawpartition2d2, l2norm, is_level_list_valid, is_valid_subband

"""
drawpartition2d2(signal, liste; width=nothing, image=nothing, fit=false)

Draw the quadtree partition described by `liste` over `signal` (image).
Optional keyword `width` controls line width; `image` may be a filename to overlay.
Returns a `Plots.Plot` object.
"""
function drawpartition2d2(signal::AbstractMatrix, liste::AbstractMatrix; width=nothing, image=nothing, fit=false)
(m, n) = size(signal)

Expand Down Expand Up @@ -77,10 +84,21 @@ module HELPER
newpos = recurspartition(p, pm + m / 2, pn + n / 2, m / 2, n / 2, liste, newpos, level + 1, width)
end

"""
l2norm(original, mutated)

Relative L2 error: returns norm(mutated - original) / norm(original).
"""
function l2norm(original::AbstractVecOrMat, mutated::AbstractVecOrMat)
return norm(mutated .- original)/ norm(original)
end

"""
is_level_list_valid(signal, list)

Quick validator that checks `signal` dimensions are even and that `list` is a valid level-list.
Returns `true` when valid, otherwise `false`.
"""
function is_level_list_valid(signal::AbstractMatrix, list::AbstractMatrix)
m,n = size(signal)

Expand Down
Loading
Loading