NXRefine 0.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. nxrefine/__init__.py +9 -0
  2. nxrefine/_version.py +24 -0
  3. nxrefine/julia/GeneralMK3D.jl +258 -0
  4. nxrefine/julia/LaplaceInterpolation.jl +25 -0
  5. nxrefine/julia/Matern1D2D.jl +229 -0
  6. nxrefine/julia/MaternKernelApproximation.jl +342 -0
  7. nxrefine/julia/__init__.py +0 -0
  8. nxrefine/julia/arbitrary_dim.jl +109 -0
  9. nxrefine/julia/get_xyzs.jl +63 -0
  10. nxrefine/julia/nexus.jl +153 -0
  11. nxrefine/julia/punch.jl +232 -0
  12. nxrefine/nxbeamline.py +313 -0
  13. nxrefine/nxdaemon.py +160 -0
  14. nxrefine/nxdatabase.py +608 -0
  15. nxrefine/nxlogger.py +103 -0
  16. nxrefine/nxorient.py +566 -0
  17. nxrefine/nxpdf.py +377 -0
  18. nxrefine/nxreduce.py +2703 -0
  19. nxrefine/nxrefine.py +2035 -0
  20. nxrefine/nxserver.py +503 -0
  21. nxrefine/nxsettings.py +188 -0
  22. nxrefine/nxsymmetry.py +176 -0
  23. nxrefine/nxutils.py +711 -0
  24. nxrefine/orient/__init__.py +0 -0
  25. nxrefine/orient/conventional.py +115 -0
  26. nxrefine/orient/niggli.py +138 -0
  27. nxrefine/orient/orientedlattice.py +139 -0
  28. nxrefine/orient/reduced.py +393 -0
  29. nxrefine/orient/scalar_utils.py +210 -0
  30. nxrefine/plugins/experiment/__init__.py +27 -0
  31. nxrefine/plugins/experiment/calibrate_powder.py +493 -0
  32. nxrefine/plugins/experiment/create_mask.py +300 -0
  33. nxrefine/plugins/experiment/edit_settings.py +149 -0
  34. nxrefine/plugins/experiment/import_scans.py +134 -0
  35. nxrefine/plugins/experiment/make_scans.py +127 -0
  36. nxrefine/plugins/experiment/new_configuration.py +301 -0
  37. nxrefine/plugins/experiment/new_experiment.py +157 -0
  38. nxrefine/plugins/experiment/new_sample.py +70 -0
  39. nxrefine/plugins/experiment/new_scan.py +269 -0
  40. nxrefine/plugins/experiment/sum_scans.py +155 -0
  41. nxrefine/plugins/refine/__init__.py +26 -0
  42. nxrefine/plugins/refine/calculate_angles.py +113 -0
  43. nxrefine/plugins/refine/choose_parameters.py +208 -0
  44. nxrefine/plugins/refine/copy_parameters.py +60 -0
  45. nxrefine/plugins/refine/define_lattice.py +227 -0
  46. nxrefine/plugins/refine/find_maximum.py +324 -0
  47. nxrefine/plugins/refine/find_peaks.py +269 -0
  48. nxrefine/plugins/refine/prepare_mask.py +162 -0
  49. nxrefine/plugins/refine/refine_lattice.py +1230 -0
  50. nxrefine/plugins/refine/transform_data.py +201 -0
  51. nxrefine/plugins/server/__init__.py +18 -0
  52. nxrefine/plugins/server/edit_settings.py +99 -0
  53. nxrefine/plugins/server/manage_server.py +276 -0
  54. nxrefine/plugins/server/manage_workflows.py +679 -0
  55. nxrefine/scripts/__init__.py +0 -0
  56. nxrefine/scripts/nxchoose.py +68 -0
  57. nxrefine/scripts/nxcombine.py +46 -0
  58. nxrefine/scripts/nxcopy.py +47 -0
  59. nxrefine/scripts/nxdatabase.py +32 -0
  60. nxrefine/scripts/nxfind.py +58 -0
  61. nxrefine/scripts/nxlink.py +45 -0
  62. nxrefine/scripts/nxload.py +45 -0
  63. nxrefine/scripts/nxmax.py +51 -0
  64. nxrefine/scripts/nxparent.py +29 -0
  65. nxrefine/scripts/nxpdf.py +51 -0
  66. nxrefine/scripts/nxprepare.py +61 -0
  67. nxrefine/scripts/nxreduce.py +80 -0
  68. nxrefine/scripts/nxrefine.py +59 -0
  69. nxrefine/scripts/nxserver.py +67 -0
  70. nxrefine/scripts/nxsettings.py +40 -0
  71. nxrefine/scripts/nxsum.py +43 -0
  72. nxrefine/scripts/nxtransform.py +56 -0
  73. nxrefine-0.1.1.dist-info/METADATA +152 -0
  74. nxrefine-0.1.1.dist-info/RECORD +79 -0
  75. nxrefine-0.1.1.dist-info/WHEEL +5 -0
  76. nxrefine-0.1.1.dist-info/entry_points.txt +23 -0
  77. nxrefine-0.1.1.dist-info/licenses/LICENSE +34 -0
  78. nxrefine-0.1.1.dist-info/licenses/LICENSE.pdf +0 -0
  79. nxrefine-0.1.1.dist-info/top_level.txt +1 -0
nxrefine/__init__.py ADDED
@@ -0,0 +1,9 @@
1
+ # -----------------------------------------------------------------------------
2
+ # Copyright (c) 2022, Argonne National Laboratory.
3
+ #
4
+ # Distributed under the terms of an Open Source License.
5
+ #
6
+ # The full license is in the file LICENSE.pdf, distributed with this software.
7
+ # -----------------------------------------------------------------------------
8
+
9
+ from ._version import version as __version__
nxrefine/_version.py ADDED
@@ -0,0 +1,24 @@
1
+ # file generated by vcs-versioning
2
+ # don't change, don't track in version control
3
+ from __future__ import annotations
4
+
5
+ __all__ = [
6
+ "__version__",
7
+ "__version_tuple__",
8
+ "version",
9
+ "version_tuple",
10
+ "__commit_id__",
11
+ "commit_id",
12
+ ]
13
+
14
+ version: str
15
+ __version__: str
16
+ __version_tuple__: tuple[int | str, ...]
17
+ version_tuple: tuple[int | str, ...]
18
+ commit_id: str | None
19
+ __commit_id__: str | None
20
+
21
+ __version__ = version = '0.1.1'
22
+ __version_tuple__ = version_tuple = (0, 1, 1)
23
+
24
+ __commit_id__ = commit_id = None
@@ -0,0 +1,258 @@
1
+
2
+ # functions: nablasq_3d_grid, return_boundary_nodes,
3
+ # return_boundary_nodes_3D, punch_holes_nexus_Cartesian,
4
+ # Matern_3d_Grid, Laplace_3D_grid,
5
+ # parallel_Matern_3DGrid, parallel_Laplace_3Dgrid
6
+
7
+ # Internal settings for caching
8
+ mutable struct Settings
9
+ A_matrix_STORE_MAX::Int64
10
+ end
11
+
12
+ # There may be up to 15 A_matrices for a 3d grid
13
+ const SETTINGS = Settings(15)
14
+
15
+ # Dict for storing A_matrices
16
+ const A_matrix = Dict{Tuple{Int64, Int64, Int64, Int64, Float64, Float64, Float64,
17
+ Float64}, Matrix{Float64}}()
18
+ """
19
+ nablasq_3d_grid(Nx,Ny)
20
+
21
+ Construct the 3D Laplace matrix
22
+
23
+ # Arguments
24
+ - `Nx::Int64`: The number of nodes in the first dimension
25
+ - `Ny::Int64`: The number of nodes in the second dimension
26
+ - `Nz::Int64`: The number of nodes in the third dimension
27
+ - `h::Float64`: Grid spacing in the first dimension
28
+ - `k::Float64`: Grid spacing in the second dimension
29
+ - `l::Float64`: Grid spacing in the third dimension
30
+
31
+ # Outputs
32
+
33
+ - `-nablasq` (discrete Laplacian, real-symmetric positive-definite) on Nx×Ny×Nz grid
34
+
35
+ """
36
+ function nablasq_3d_grid(Nx, Ny, Nz, h, k, l)
37
+ #haskey(A_matrix, (Nx, Ny, Nz, 1, 0.0, h, k, l)) && return A_matrix[(Nx, Ny, Nz, 1, 0.0, h, k, l)]
38
+ o₁ = ones(Nx) / h
39
+ del1 = spdiagm_nonsquare(Nx + 1, Nx, -1 => -o₁, 0 => o₁)
40
+ o₂ = ones(Ny) / k
41
+ del2 = spdiagm_nonsquare(Ny + 1, Ny, -1 => -o₂,0 => o₂)
42
+ O3 = ones(Nz) / l
43
+ del3 = spdiagm_nonsquare(Nz + 1, Nz, -1 => -O3, 0 => O3)
44
+ A3D = (kron(sparse(I, Nz, Nz), sparse(I, Ny, Ny), del1'*del1) +
45
+ kron(sparse(I, Nz, Nz), del2' * del2, sparse(I, Nx, Nx)) +
46
+ kron(del3' * del3, sparse(I, Ny, Ny), sparse(I, Nx, Nx)))
47
+ BoundaryNodes, xneighbors, yneighbors, zneighbors =
48
+ return_boundary_nodes(Nx, Ny, Nz)
49
+ count = 1
50
+ for i in BoundaryNodes
51
+ A3D[i, i] = 0.0
52
+ A3D[i, i] = A3D[i, i] + xneighbors[count] / h ^ 2 +
53
+ yneighbors[count] / k ^ 2 + zneighbors[count] / l ^ 2
54
+ count = count + 1
55
+ end
56
+ #length(A_matrix) < SETTINGS.A_matrix_STORE_MAX && (A_matrix[(Nx, Ny, Nz, 1, 0.0, h, k, l)] = A3D)
57
+ #if length(A_matrix) == SETTINGS.A_matrix_STORE_MAX
58
+ # @warn "A_matrix cache full, no longer caching Laplace interpolation matrices."
59
+ #end
60
+ return A3D
61
+ end
62
+
63
+ """ Helper function to give the matern matrix """
64
+ function _Matern_matrix(Nx, Ny, Nz, m, eps, h, k, l)
65
+ #haskey(A_matrix, (Nx, Ny, Nz, m, eps, h, k, l)) && return A_matrix[(Nx, Ny, Nz, m, eps, h, k, l)]
66
+ A3D = nablasq_3d_grid(Nx, Ny, Nz, h, k, l)
67
+ sizeA = size(A3D, 1)
68
+ for i = 1:sizeA
69
+ A3D[i, i] = A3D[i, i] + eps^2
70
+ end
71
+ A3DMatern = A3D^m
72
+ #length(A_matrix) < SETTINGS.A_matrix_STORE_MAX && (A_matrix[(Nx, Ny, Nz, m, eps, h, k, l)] = A3DMatern)
73
+ #if length(A_matrix) == SETTINGS.A_matrix_STORE_MAX
74
+ # @warn "A_matrix cache full, no longer caching Laplace interpolation matrices."
75
+ #end
76
+ A3DMatern
77
+ end
78
+
79
+ """
80
+
81
+ matern_3d_grid(imgg, discard, m, eps, h, k, l)
82
+
83
+ Interpolates a single punch
84
+
85
+ ...
86
+ # Arguments
87
+ - `imgg`: the matrix containing the image
88
+ - `discard::Union{Vector{CartesianIndex{3}}}, Vector{Int64}}`: the linear or
89
+ Cartesian indices of the values to be filled
90
+ - `m::Int64 = 1` : Matern parameter
91
+ - `eps::Float64 = 0.0`: Matern parameter eps
92
+ - `h = 1.0`: Aspect ratio in the first dimension
93
+ - `k = 1.0`: Aspect ratio in the second dimension
94
+ - `l = 1.0`: Aspect ratio in the third dimension
95
+
96
+ # Outputs
97
+ - array containing the restored image
98
+ ...
99
+
100
+ """
101
+ function matern_3d_grid(imgg, discard::Union{Vector{CartesianIndex{3}}, Vector{Int64}},
102
+ m::Int64 = 1, eps::Float64 = 0.0,
103
+ h = 1.0, k = 1.0, l = 1.0)
104
+ Nx, Ny, Nz = size(imgg)
105
+ A3D = (eps == 0.0)&&(m == 1) ?
106
+ nablasq_3d_grid(Nx, Ny, Nz, h, k, l) :
107
+ _Matern_matrix(Nx, Ny, Nz, m, eps, h, k, l)
108
+ totalsize = Nx * Ny * Nz
109
+ C = sparse(I, totalsize, totalsize)
110
+ rhs_a = copy(imgg)[:]
111
+ for i in discard
112
+ j = (typeof(i) <: CartesianIndex) ? LinearIndices(imgg)[i] : i
113
+ C[j, j] = 0.0
114
+ rhs_a[j] = 0.0
115
+ end
116
+ Id = sparse(I, totalsize, totalsize)
117
+ u = ((C - (Id - C) * A3D)) \ rhs_a
118
+ return reshape(u, Nx, Ny, Nz)
119
+ end
120
+
121
+ # Add m pixels around the punch and then intersect with the size of the full
122
+ # image (3D only)
123
+ function pad_intersect(discard, m, Nx, Ny, Nz)
124
+ B = bounding_box(discard)
125
+ fi, li = (first(B) - CartesianIndex(m, m, m), last(B) + CartesianIndex(m, m, m))
126
+ return intersect_box(fi:li, CartesianIndices((Nx,Ny,Nz)))
127
+ end
128
+
129
+ function get_Qw_maxmin(wpoints)
130
+ Qw_min, Qw_max = (Int64(floor(minimum(wpoints))), Int64(ceil(maximum(wpoints))))
131
+ end
132
+
133
+ """
134
+
135
+ matern_w_punch(imgg, Qh_min, Qh_max, Qk_min, Qk_max, Ql_min, Ql_max, m, eps, h, k, l, symm)
136
+
137
+ Interpolate, in serial, multiple punches
138
+
139
+ ...
140
+ # Arguments
141
+ - `imgg`: the matrix containing the image
142
+ - ` Qh_min, Qh_max, Qk_min, Qk_max, Ql_min, Ql_max::Int64`: the extents in h,k,l resp
143
+ - `m::Int64 = 1` : Matern parameter
144
+ - `eps::Float64 = 0.0`: Matern parameter eps
145
+ - `h = 1.0`: Aspect ratio in the first dimension
146
+ - `k = 1.0`: Aspect ratio in the second dimension
147
+ - `l = 1.0`: Aspect ratio in the third dimension
148
+
149
+ # Outputs
150
+ - array containing the interpolated image
151
+
152
+ # Example
153
+
154
+ ```<julia-repl>
155
+ h = k = l = 1.0
156
+ symm = 'A'
157
+ Nx = Ny = Nz = 61
158
+ radius = (0.5, 0.5, 0.5 )
159
+ Qh_min = Qk_min = Ql_min = -3.0
160
+ Qh_max = Qk_max = Ql_max = 3.0
161
+ xpoints = ypoints = zpoints = LinRange(Qh_min, Qh_max, Nx)
162
+ imgg = rand(Nx, Ny, Nz)
163
+ m = 1
164
+ eps = 0.0
165
+ interp = matern_w_punch(imgg, #Qh_min, Qh_max, Qk_min, Qk_max, Ql_min, Ql_max, radius,
166
+ radius, xpoints, ypoints, zpoints, m, eps,
167
+ h, k, l, symm);
168
+ ```
169
+
170
+ ...
171
+ """
172
+ function matern_w_punch(imgg, radius, xpoints, ypoints, zpoints,
173
+ m = 1, eps = 0.0, h = 1.0, k = 1.0, l = 1.0, symm = 'G';
174
+ return_punch_locs = false)
175
+ Qh_min, Qh_max = get_Qw_maxmin(xpoints)
176
+ Qk_min, Qk_max = get_Qw_maxmin(ypoints)
177
+ Ql_min, Ql_max = get_Qw_maxmin(zpoints)
178
+ radius_x, radius_y, radius_z = (typeof(radius) <: Tuple) ? radius :
179
+ (radius, radius, radius)
180
+ dx, dy, dz = (xpoints[2] - xpoints[1], ypoints[2] - ypoints[1],
181
+ zpoints[2] - zpoints[1])
182
+ rpx, rpy, rpz = (Int64(round(radius_x/dx)) + m, Int64(round(radius_y/dy)) + m,
183
+ Int64(round(radius_z/dz))+ m)
184
+ Nx, Ny, Nz = (length(xpoints), length(ypoints), length(zpoints))
185
+ new_imgg = copy(imgg);
186
+ exclusion_rule = center_check(symm)
187
+ # find the first center
188
+ (cpx, cpy, cpz) = (findmin(abs.(xpoints .- Qh_min))[2],
189
+ findmin(abs.(ypoints .- Qk_min))[2],
190
+ findmin(abs.(zpoints .- Ql_min))[2])
191
+ stridex, stridey, stridez = (-cpx, -cpy, -cpz) .+ (findmin(abs.(xpoints .- (Qh_min + 1)))[2],
192
+ findmin(abs.(ypoints .- (Qk_min + 1)))[2],
193
+ findmin(abs.(zpoints .- (Ql_min + 1)))[2])
194
+ punch_locs = return_punch_locs ? ones(Int64, size(imgg)) : nothing
195
+ # Threads.@threads for c in centers
196
+ for (ih, h) in enumerate(Qh_min:Qh_max)
197
+ minpx = maximum([1, cpx + (ih - 1) * stridex - rpx])
198
+ maxpx = minimum([cpx + (ih - 1) * stridex + rpx, Nx])
199
+ for (ik, k) in enumerate(Qk_min:Qk_max)
200
+ minpy = maximum([1, cpy + (ik - 1) * stridey - rpy])
201
+ maxpy = minimum([cpy + (ik - 1) * stridey + rpy, Ny])
202
+ for (il, l) in enumerate(Ql_min:Ql_max)
203
+ minpz = maximum([1, cpz + (il - 1) * stridez - rpz])
204
+ maxpz = minimum([cpz + (il - 1) * stridez + rpz, Nz])
205
+ if exclusion_rule(h, k, l)
206
+ d = punch_3D_cart((h,k,l), radius, xpoints[minpx:maxpx],
207
+ ypoints[minpy:maxpy],
208
+ zpoints[minpz:maxpz])
209
+ # Interpolate
210
+ new_imgg[minpx:maxpx, minpy:maxpy, minpz:maxpz] = matern_3d_grid(
211
+ imgg[minpx:maxpx, minpy:maxpy, minpz:maxpz], d, m,
212
+ eps, h, k, l);
213
+ if return_punch_locs
214
+ punch_locs[d] .= 0
215
+ end
216
+ end
217
+ end
218
+ end
219
+ end
220
+ if return_punch_locs
221
+ return new_imgg, punch_locs
222
+ else
223
+ return new_imgg
224
+ end
225
+ end
226
+ # function matern_w_punch(imgg, Qh_min, Qh_max, Qk_min, Qk_max, Ql_min, Ql_max, radius,
227
+ # xpoints, ypoints, zpoints,
228
+ # m = 1, eps = 0.0, h = 1.0, k = 1.0, l = 1.0, symm = 'G')
229
+ # centers = center_list(symm, Qh_min, Qh_max, Qk_min, Qk_max, Ql_min, Ql_max)
230
+ # radius_x, radius_y, radius_z = (typeof(radius) <: Tuple) ? radius :
231
+ # (radius, radius, radius)
232
+ # dx, dy, dz = (xpoints[2] - xpoints[1], ypoints[2] - ypoints[1],
233
+ # zpoints[2] - zpoints[1])
234
+ # rpx, rpy, rpz = (Int64(round(radius_x/dx)), Int64(round(radius_y/dy)),
235
+ # Int64(round(radius_z/dz)))
236
+ # Nx, Ny, Nz = (length(xpoints), length(ypoints), length(zpoints))
237
+ # new_imgg = copy(imgg);
238
+ # # Threads.@threads for c in centers
239
+ # for c in centers
240
+ # (cpx, cpy, cpz) = (findmin(abs.(xpoints .- c[1]))[2],
241
+ # findmin(abs.(ypoints .- c[2]))[2],
242
+ # findmin(abs.(zpoints .- c[3]))[2])
243
+ # minpx, minpy, minpz = (maximum([1, cpx - (rpx + m)]),
244
+ # maximum([1, cpy - (rpy + m)]),
245
+ # maximum([1, cpz - (rpz + m)]))
246
+ # maxpx, maxpy, maxpz = (minimum([Nx, cpx + (rpx + m)]),
247
+ # minimum([Ny, cpy + (rpx + m)]),
248
+ # minimum([Nz, cpz + (rpz + m)]))
249
+ # d = punch_3D_cart(c, radius, xpoints[minpx:maxpx], ypoints[minpy:maxpy],
250
+ # zpoints[minpz:maxpz])
251
+ # # Interpolate
252
+ # new_imgg[minpx:maxpx, minpy:maxpy, minpz:maxpz] = matern_3d_grid(
253
+ # imgg[minpx:maxpx, minpy:maxpy, minpz:maxpz], d, m, eps, h, k, l);
254
+ # end
255
+ # return new_imgg
256
+ # end
257
+
258
+
@@ -0,0 +1,25 @@
1
+ module LaplaceInterpolation
2
+
3
+ using LinearAlgebra, SparseArrays
4
+
5
+ include("Matern1D2D.jl")
6
+ export nablasq_grid, bdy_nodes, matern_1d_grid, matern_2d_grid
7
+
8
+ include("GeneralMK3D.jl")
9
+ export nablasq_3d_grid, matern_3d_grid, matern_w_punch
10
+
11
+ include("MaternKernelApproximation.jl")
12
+ export spdiagm_nonsquare, return_boundary_nodes
13
+ export Matern3D_Grid, Parallel_Matern3D_Grid
14
+
15
+ include("punch.jl")
16
+ export punch_holes_3D, punch_holes_2D, punch_3d_cart, center_list
17
+
18
+ include("nexus.jl")
19
+ # These functions are unexported
20
+
21
+ # Only works with juliia v 1.6 and higher
22
+ include("arbitrary_dim.jl")
23
+ export nablasq_arb, interp
24
+
25
+ end
@@ -0,0 +1,229 @@
1
+
2
+ # Helper code
3
+
4
+ """
5
+ spdiagm_nonsquare(m, n, args...)
6
+
7
+ Construct a sparse diagonal matrix from Pairs of vectors and diagonals. Each
8
+ vector arg.second will be placed on the arg.first diagonal. By default (if
9
+ size=nothing), the matrix is square and its size is inferred from kv, but a
10
+ non-square size m×n (padded with zeros as needed) can be specified by passing
11
+ m,n as the first arguments.
12
+
13
+ # Arguments
14
+ - `m::Int64`: First dimension of the output matrix
15
+ - `n::Int64`: Second dimension of the output matrix
16
+ - `args::Tuple{T} where T<:Pair{<:Integer,<:AbstractVector}`
17
+
18
+ # Outputs
19
+
20
+ - sparse matrix of size mxn containing the values in args
21
+
22
+ """
23
+ function spdiagm_nonsquare(m, n, args...)
24
+ I, J, V = SparseArrays.spdiagm_internal(args...)
25
+ return sparse(I, J, V, m, n)
26
+ end
27
+
28
+ # One-dimensional codes
29
+
30
+ """
31
+ nablasq_grid(n, h)
32
+
33
+ Laplacian matrix on a 1D grid
34
+
35
+ # Arguments:
36
+ - `n`: Number of points
37
+ - `h`: Aspect ratio
38
+
39
+ # Outputs:
40
+ - discrete Laplacian matrix
41
+ """
42
+ function nablasq_grid(n::Int64, h::Float64 = 1.0)
43
+ o = ones(n) / h
44
+ del = spdiagm_nonsquare(n + 1, n, -1 => -o, 0 => o)
45
+ A1D = del' * del
46
+ A1D[1, 1] = 1.0 / h ^ 2
47
+ A1D[n, n] = 1.0 / h ^ 2
48
+ return A1D
49
+ end
50
+
51
+ """
52
+
53
+ matern_1d_grid(y, idx, m, eps, h)
54
+
55
+ Matern Interpolation in one dimension
56
+
57
+ # Arguments:
58
+ - `y`: the vector of y's for which the values are known
59
+ - `idx`: the vector of indices for which values are to be interpolated
60
+ - `m::Int64 = 1`: Matern parameter m
61
+ - `eps = 0.0`: Matern parameter eps
62
+ - `h = 1.0`: aspect ratio
63
+
64
+ # Outputs:
65
+ - vector of interpolated data
66
+
67
+ # Example:
68
+ ```<julia-repl>
69
+ x = 1:100
70
+ h = x[2] - x[1]
71
+ y = sin.(2 * pi * x * 0.2)
72
+ discard = randperm(100)[1:50]
73
+ # Laplace interpolation
74
+ y_lap = matern_1d_grid(y, discard, 1, 0.0, h)
75
+ # Matern interpolation
76
+ y_mat = matern_1d_grid(y, discard, 2, 0.1, h)
77
+ ```
78
+
79
+ """
80
+ function matern_1d_grid(y::Vector{T}, idx::Vector{Int64},
81
+ m::Int64 = 1, eps = 0.0, h::Float64 = 1.0) where{T<:Number}
82
+ n = length(y)
83
+ A1D = nablasq_grid(n, h)
84
+ C = sparse(I, n, n)
85
+ for i in idx
86
+ C[i, i] = 0.0
87
+ end
88
+ if ((eps == 0)||(eps == 0.0)) && (m == 1)
89
+ # Laplace Interpolation
90
+ return ((C - (sparse(I, n, n) - C) * A1D)) \ (C * y)
91
+ else
92
+ # Matern Interpolation
93
+ for i = 1:size(A1D,1)
94
+ A1D[i, i] = A1D[i, i] + eps^2
95
+ end
96
+ A1DM = A1D ^ m
97
+ return ((C - (sparse(I, n, n) - C) * A1DM)) \ (C * y)
98
+ end
99
+ end
100
+
101
+ # Two dimensional codes
102
+
103
+ """
104
+ bdy_nodes(Nx, Ny)
105
+
106
+ ...
107
+ # Arguments
108
+
109
+ - `Nx::Int64`: the number of points in the first dimension
110
+ - `Ny::Int64`: the number of points in the second dimension
111
+ ...
112
+
113
+ ...
114
+ # Outputs
115
+ - vector containing the indices of coordinates on the boundary of the 2D rectangle
116
+ ...
117
+
118
+ """
119
+ function bdy_nodes(Nx, Ny)
120
+ bdy = []
121
+ xnb = []
122
+ ynb = []
123
+ counter = 0
124
+ for j = 1:Ny
125
+ for i = 1:Nx
126
+ counter += 1
127
+ if (j == 1 || j == Ny || i == 1 || i == Nx)
128
+ bdy = push!(bdy, counter)
129
+ if (j == 1 || j == Ny)
130
+ push!(ynb, 1)
131
+ else
132
+ push!(ynb, 2)
133
+ end
134
+ if (i == 1 || i == Nx)
135
+ push!(xnb, 1)
136
+ else
137
+ push!(xnb, 2)
138
+ end
139
+ end
140
+ end
141
+ end
142
+ return bdy, xnb, ynb
143
+ end
144
+
145
+ """
146
+ nablasq_grid(Nx, Ny, h, k)
147
+
148
+ Laplacian matrix on a 2D grid
149
+
150
+ # Arguments:
151
+ - `Nx::Int64`: Number of points in first dimension
152
+ - `Ny::Int64`: Number of points in second dimension
153
+ - `h::Float64`: Aspect ratio in first dimension
154
+ - `k::Float64`: Aspect ratio in second dimension
155
+
156
+ # Outputs:
157
+ - discrete Laplacian matrix in 2D
158
+ """
159
+ function nablasq_grid(Nx::Int64, Ny::Int64, h::Float64, k::Float64)
160
+ o1 = ones(Nx) / h
161
+ del1 = spdiagm_nonsquare(Nx + 1, Nx, -1 => -o1, 0 => o1)
162
+ o2 = ones(Ny) / k
163
+ del2 = spdiagm_nonsquare(Ny + 1, Ny, -1 => -o2,0 => o2)
164
+ A2D = (kron(sparse(I, Ny, Ny), del1' * del1) +
165
+ kron(del2' * del2, sparse(I, Nx, Nx)))
166
+ bdy, xnb, ynb = bdy_nodes(Nx, Ny)
167
+ count = 1
168
+ for i in bdy
169
+ A2D[i, i] = 0.0
170
+ A2D[i, i] = A2D[i, i] + xnb[count] / h ^ 2 + ynb[count] / k ^ 2
171
+ count += 1
172
+ end
173
+ return A2D
174
+ end
175
+
176
+ """
177
+
178
+ matern_2d_grid(mat, discard, m, eps, h, k)
179
+
180
+ ...
181
+ # Arguments
182
+ - `mat`: the matrix containing the image
183
+ - `idx`: the linear indices of the nodes to be discarded
184
+ - `eps`: Matern parameter eps
185
+ - `m`: The Matern exponent (integer)
186
+ - `h`: The aspect ratio in the first dimension
187
+ - `k`: The aspect ratio in the second dimension
188
+
189
+ # Outputs
190
+ - matrix containing the interpolated image
191
+
192
+ # Example:
193
+
194
+ ```<julia-repl>
195
+ x = y = 1:30
196
+ h = k = x[2] - x[1]
197
+ y = sin.(2 * pi * x * 0.2) * cos.(2 * pi * y * 0.3)
198
+ discard = randperm(900)[1:450]
199
+ # Laplace interpolation
200
+ y_lap = matern_2d_grid(y, discard, 1, 0.0, h, k)
201
+ # Matern interpolation
202
+ y_mat = matern_2d_grid(y, discard, 2, 0.1, h, k)
203
+ ...
204
+
205
+ """
206
+ function matern_2d_grid(mat::Matrix, discard::Vector, m::Int64 = 1, eps = 0.0,
207
+ h::Float64 = 1.0, k::Float64 = 1.0)
208
+ rows, columns = size(mat)
209
+ A2D = nablasq_grid(rows, columns, h, k)
210
+ sizeA = size(A2D, 1)
211
+ C = sparse(I, sizeA, sizeA)
212
+ for i in discard
213
+ C[i, i] = 0.0
214
+ end
215
+ if ((m == 1)||(m == 1.0)) && (eps == 0.0)
216
+ # Laplace interpolation
217
+ u = ((C - (sparse(I, sizeA, sizeA) - C) * A2D)) \ (C * mat[:])
218
+ return reshape(u, rows, columns)
219
+ else
220
+ # Matern interpolation
221
+ for i = 1:sizeA
222
+ A2D[i,i] = A2D[i,i] + eps^2
223
+ end
224
+ A2D = A2D^m
225
+ u = ((C - (sparse(I, sizeA, sizeA) - C) * A2D)) \ (C * mat[:])
226
+ return reshape(u, rows, columns)
227
+ end
228
+ end
229
+