Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved Grid_points and rand_p #50

Open
wants to merge 35 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
6e19de0
Gridpoint improvement (#1)
ryboselm Jun 4, 2024
e87ea6d
Add RNG passing to rand_p
ryanlevy Jun 5, 2024
f4032a2
add default rng tests
ryboselm Jun 5, 2024
5d3c2a2
Merge pull request #2 from ryboselm/rng
ryboselm Jun 5, 2024
f85ab83
Methods to convert Data and Functions into QTT format (#3)
ryboselm Jun 20, 2024
ec1333a
get rid of warning about redefining default_dimension()
ryboselm Jun 26, 2024
87c7477
Merge branch 'main' into dev
ryboselm Jul 3, 2024
3a966d4
update interpolation functions to take complex coefficients
ryboselm Jul 19, 2024
e4504b9
remove coeffs as an output of function_itn
ryboselm Jul 19, 2024
78e4eea
remove coefficients output from examples
ryboselm Jul 19, 2024
58a789a
added clenshaw interpolation (#5)
ryboselm Jul 26, 2024
0cd8f57
clean up old examples
ryboselm Nov 1, 2024
e86726c
Merge remote-tracking branch 'upstream/main' into dev
ryboselm Nov 1, 2024
620d7cc
stop tracking config files
ryboselm Nov 1, 2024
64c73ed
oops add back .gitignore
ryboselm Nov 1, 2024
22c3707
formatting
ryboselm Nov 1, 2024
62d23f7
test case
ryboselm Nov 1, 2024
f03c518
formatting
ryboselm Nov 1, 2024
bd4e0d4
added back grid_points tests, made naming of args more consistent, cl…
ryboselm Nov 4, 2024
050cb3e
added functional grid_points and rand_p functions with passing tests
ryboselm Nov 5, 2024
bac29f1
formatting
ryboselm Nov 5, 2024
3e37e32
add test cases for interpolation_functions
ryboselm Nov 7, 2024
554100b
added dimension specification inside interpolation_functions and made…
ryboselm Nov 7, 2024
28ad64d
removed interpolation changes
ryboselm Nov 8, 2024
7b1ea30
Merge branch 'main' into grid_points
ryboselm Nov 8, 2024
fd31bb2
add GraphRecipes dep
ryboselm Nov 8, 2024
108d3ab
formatting
ryboselm Nov 8, 2024
8e319c2
re-organize test sets for indexmaps
ryboselm Nov 14, 2024
f81e4bc
multi-dimensional grid_points
ryboselm Nov 14, 2024
3923d75
simplify grid_points exact_grid condition significantly
ryboselm Nov 14, 2024
ddbdc33
formatting
ryboselm Nov 14, 2024
5743314
clean up grid_points and rand_p and their tests
ryboselm Jan 15, 2025
f942557
formatting
ryboselm Jan 15, 2025
e157242
generalize round_to_nearest_exact_point and added complexindexmap ran…
ryboselm Jan 15, 2025
1b64e12
formatting
ryboselm Jan 15, 2025
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
3 changes: 2 additions & 1 deletion src/ITensorNumericalAnalysis.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ export AbstractIndexMap,
calculate_ind_values,
dimension,
dimensions,
grid_points
grid_points,
rand_p
export IndsNetworkMap,
continuous_siteinds,
complex_continuous_siteinds,
Expand Down
8 changes: 7 additions & 1 deletion src/IndexMaps/abstractindexmap.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ using Base: Base
using Dictionaries: Dictionary, set!
using ITensors: ITensors, Index, dim
using ITensorNetworks: IndsNetwork, vertex_data

using Random: AbstractRNG, default_rng
abstract type AbstractIndexMap{VB,VD} end

#These functions need to be defined on the concrete type for implementation
Expand Down Expand Up @@ -153,3 +153,9 @@ function grid_points(imap::AbstractIndexMap, d::Int)
L = length(dimension_inds(imap, d))
return grid_points(imap, base^L, d)
end

function rand_p(rng::AbstractRNG, imap::AbstractIndexMap)
return [rand_p(rng, imap, i) for i in 1:dimension(imap)]
end

rand_p(imap::AbstractIndexMap, args...) = rand_p(default_rng(), imap, args...)
13 changes: 13 additions & 0 deletions src/IndexMaps/complexindexmap.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ using Base: Base
using Dictionaries: Dictionaries, Dictionary, set!
using ITensors: ITensors, Index, dim, hastags
using ITensorNetworks: IndsNetwork, vertex_data
using Random: AbstractRNG

struct ComplexIndexMap{VB,VD,VR} <: AbstractIndexMap{VB,VD}
index_digit::VB
Expand Down Expand Up @@ -142,3 +143,15 @@ function grid_points(imap::ComplexIndexMap, N::Int, d::Int)
]
return filter(x -> real(x) < 1 && imag(x) < 1, grid_points)
end

"""
Picks a random grid point from `imap` given a dimension
"""
function rand_p(rng::AbstractRNG, imap::ComplexIndexMap, d::Integer)
dims = dim.(dimension_inds(imap, d))
@assert all(y -> y == first(dims), dims)
base = float(first(dims))
Lre, Lim = length(real_indices(imap, d)), length(imag_indices(imap, d))
return rand(rng, 0:(big(base)^Lre - 1)) / big(base)^Lre +
im * rand(rng, 0:(big(base)^Lim - 1)) / big(base)^Lim
end
97 changes: 92 additions & 5 deletions src/IndexMaps/realindexmap.jl
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should also add support for multidimensional grid points.

Like we have a function where we pass a vector of dimensions and then zip up the result of grid_points called on each of the dimensions

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you elaborate more on what your idea for this would look like?

for example, if you passed in a vector dimensions = [1,3], and suppose that grid_points(s,1) = [0, 1] and grid_points(s,3) = [0.3, 0.4, 0.5], would grid_points(s, [1, 3]) then be something like [[0, 0.3], [0, 0.4], [0, 0.5], [1, 0.3], [1, 0.4], [1, 0.5]]?

Copy link
Owner

@JoeyT1994 JoeyT1994 Nov 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes so if for each dimension I you input you generate some vector of Ni points then it would return the iterative product which consists of every unique combination of points:

e.g. [0.25, 0.5], [0.625, 0.975, 0.9875] -> [(0.25, 0.625), (0.25, 0.975),(0.25, 0.9875), (0.5, 0.625), (0.5, 0.975), (0.5, 0.9875)]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it be better to return an array of tuples or an array of arrays here?

I initially leaned towards having an array of arrays because evaluate takes in an array to specify the point it should evaluate the function at.

Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ using Base: Base
using Dictionaries: Dictionaries, Dictionary, set!
using ITensors: ITensors, Index, dim
using ITensorNetworks: IndsNetwork, vertex_data
using Random: AbstractRNG

struct RealIndexMap{VB,VD} <: AbstractIndexMap{VB,VD}
index_digit::VB
Expand Down Expand Up @@ -75,12 +76,98 @@ function calculate_ind_values(imap::RealIndexMap, xs::Vector, dims::Vector{Int})
return ind_to_ind_value_map
end

function grid_points(imap::RealIndexMap, N::Int, d::Int)
"""
grid_points(imap, N, d, span; exact_grid=true, enforced=[])

Gives `N` grid points from a given dimension of `imap` within a specified range.

# Arguments
- `imap::RealIndexMap`: An IndexMap specifying the structure of the TN being used
- `N::Int`: The number of grid points requested.
- `d::Int` The index of the dimension of `imap` requested
- `span::AbstractVector{<:Number}`: A two element number vector [a,b] with 0≤a<b≤1. The right endpoint of this span is not included as a gridpoint in the output.
- `exact_grid::Bool`: Flag specifying whether the function should give exact grid points
(note: using `exact_grid=true` may cause less than `N` grid points to be returned)
- `enforced::AbstractVector{<:Number}`: A list of points that we want to enforce to show up in the grid.
"""
function grid_points(
imap::RealIndexMap,
N::Int,
d::Int;
span::AbstractVector{<:Number}=[0, 1],
exact_grid::Bool=true,
enforced=[],
)
if length(span) != 2 || span[1] >= span[2] || span[1] < 0 || span[2] > 1
throw(
"expected a two-element vector [a,b] with 0≤a<b≤1 as input span, instead found $span"
)
end
dims = dim.(dimension_inds(imap, d))
@assert all(y -> y == first(dims), dims)
base = first(dims)
L = length(dimension_inds(imap, d))

# generate grid_points within the span (exclusive of right endpoint)
grid_points = collect(range(span[1], span[2] - (span[2] - span[1]) / N; length=N))
if exact_grid
for (i, point) in enumerate(grid_points)
grid_points[i] = round_to_nearest_exact_point(point, L)
ryboselm marked this conversation as resolved.
Show resolved Hide resolved
end
# define lambda function
# round_near = point -> round_to_nearest_exact_point(point, L)
# grid_points = map(round_near, grid_points)
grid_points = unique(grid_points)
end

# add enforced points
if !isempty(enforced)
grid_points = sort(unique(vcat(grid_points, enforced_points)))
end

return grid_points
end

function round_to_nearest_exact_point(point::Number, L::Int)
if point < 0 || point >= 1
ryboselm marked this conversation as resolved.
Show resolved Hide resolved
throw("Input point must be between 0 and 1")
end
return round(point * 2.0^L) / 2.0^L
ryboselm marked this conversation as resolved.
Show resolved Hide resolved
end

function grid_points(imap::RealIndexMap, d::Int; kwargs...)
dims = dim.(dimension_inds(imap, d))
@assert all(y -> y == first(dims), dims)
base = dims[d]
L = length(dimension_inds(imap, d))
return grid_points(imap, base^L, d; kwargs...)
end

grid_points(imap::RealIndexMap; kwargs...) = grid_points(imap, 1; kwargs...)

#multi-dimensional grid_points
function grid_points(imap::RealIndexMap, Ns::Vector{Int}, dims::Vector{Int}; kwargs...)
if length(Ns) != length(dims)
throw("length of Ns and dims do not match!")
end
coords = [grid_points(imap, pair[1], pair[2]; kwargs...) for pair in zip(Ns, dims)]
gp = Base.Iterators.product(coords...)
return [collect(point) for point in gp]
ryboselm marked this conversation as resolved.
Show resolved Hide resolved
end

function grid_points(imap::RealIndexMap, dims::Vector{Int}; kwargs...)
coords = [grid_points(imap, d; kwargs...) for d in dims]
gp = Base.Iterators.product(coords...)
return [collect(point) for point in gp]
end

"""
Picks a random grid point from `imap` given a dimension
"""
function rand_p(rng::AbstractRNG, imap::RealIndexMap, d::Integer)
dims = dim.(dimension_inds(imap, d))
@assert all(y -> y == first(dims), dims)
base = float(first(dims))
base = dims[d]
L = length(dimension_inds(imap, d))
a = round(base^L / N)
grid_points = [i * (a / base^L) for i in 0:(N + 1)]
return filter(x -> x < 1, grid_points)
return rand(rng, 0:(big(base)^L - 1)) / big(base)^L
end
10 changes: 10 additions & 0 deletions src/indsnetworkmap.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ using NamedGraphs.GraphsExtensions: rem_vertex
using ITensors: ITensors
using ITensorNetworks:
ITensorNetworks, AbstractIndsNetwork, IndsNetwork, data_graph, underlying_graph
using Random: AbstractRNG

struct IndsNetworkMap{V,I,IN<:IndsNetwork{V,I},IM<:AbstractIndexMap} <:
AbstractIndsNetwork{V,I}
Expand Down Expand Up @@ -95,6 +96,7 @@ for f in [
:calculate_ind_values,
:calculate_p,
:grid_points,
:rand_p,
:index_value_to_scalar,
:index_values_to_scalars,
]
Expand All @@ -104,6 +106,14 @@ for f in [
end
end
end
# Forward RNG functionality
for f in [:rand_p]
@eval begin
function $f(rng::AbstractRNG, inm::IndsNetworkMap, args...; kwargs...)
return $f(rng, indexmap(inm), args...; kwargs...)
end
end
end

#Functions on indsnetwork that don't seem to autoforward
function ITensors.inds(inm::IndsNetworkMap, args...; kwargs...)
Expand Down
89 changes: 88 additions & 1 deletion test/test_indexmaps.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ using Test
using ITensorNumericalAnalysis

using NamedGraphs: vertices
using NamedGraphs.NamedGraphGenerators: named_grid
using NamedGraphs.NamedGraphGenerators: named_grid, named_comb_tree
using NamedGraphs.GraphsExtensions: is_tree
using ITensors: siteinds, inds
using Dictionaries: Dictionary
Expand Down Expand Up @@ -70,3 +70,90 @@ Random.seed!(1234)
xyzvals ≈ xyzvals_approx
end
end

@testset "grid_points tests" begin
@testset "test grid_points irregular span" begin
L = 16
base = 2
g = named_comb_tree((2, L ÷ 2))
s = continuous_siteinds(g; map_dimension=2)

#first set -- irregular span
N = 125
a = 0.12
b = 0.95

test_gridpoints = grid_points(s, N, 1; span=[a, b])
ryboselm marked this conversation as resolved.
Show resolved Hide resolved
@test length(test_gridpoints) == N
@test test_gridpoints[1] >= a
@test test_gridpoints[end] < b
end

@testset "test grid_points spacing" begin
L = 16
g = named_comb_tree((2, L ÷ 2))
s = continuous_siteinds(g; map_dimension=2)

#second set
N = 32
a = 0.25
b = 0.5
test2 = grid_points(s, N, 1; span=[a, b])
@test length(test2) == N
@test test2[1] >= a
@test test2[end] < b
internal = (test2[2] - test2[1])
left = (test2[1] - a)
right = (b - test2[end])
@test internal >= left && internal >= right
ryboselm marked this conversation as resolved.
Show resolved Hide resolved
ryboselm marked this conversation as resolved.
Show resolved Hide resolved
end

@testset "test grid_points spacing 2" begin
L = 16
g = named_comb_tree((2, L ÷ 2))
s = continuous_siteinds(g; map_dimension=2)
a = 0.25
b = 0.5

#third set
test3 = grid_points(s, 1)
@test length(test3) == 256
@test test3[1] >= 0
@test test3[end] < 1
internal = (test3[2] - test3[1])
left = (test3[1] - a)
right = (b - test3[end])
@test internal >= left && internal >= right
end

@testset "test grid_points high precision" begin
#fourth set -- very large L
L = 140
base = 2
g = named_comb_tree((2, L ÷ 2))
s = continuous_siteinds(g; map_dimension=2)
n_grid = 16
@test length(grid_points(s, n_grid, 1)) == n_grid
end
end

@testset "test rand_p" begin
#test the rand_p() function to see if it succeeds on large L
L = 140
g = named_comb_tree((2, L ÷ 2))
s = continuous_siteinds(g; map_dimension=2)
ψ = cos_itn(s; dim=1) * cos_itn(s; dim=2)

#test the use of seedeed randomness
rng = Random.Xoshiro(42)
rand_gridpoint1 = rand_p(rng, s)
rand_gridpoint2 = rand_p(rng, s, 1)
ryboselm marked this conversation as resolved.
Show resolved Hide resolved
x = real(ITensorNumericalAnalysis.evaluate(ψ, rand_gridpoint1))
@test x >= -1 && x <= 1 # check to make sure ψ can be evaluated at these points

#test the use of default rng
default_rng_gridpoint1 = rand_p(s)
default_rng_gridpoint2 = rand_p(s, 1)
ryboselm marked this conversation as resolved.
Show resolved Hide resolved
y = real(ITensorNumericalAnalysis.evaluate(ψ, default_rng_gridpoint1))
@test y >= -1 && y <= 1 # check to make sure ψ can be evaluated at these points
end
Loading