<commit_before>"""
module GenS

Utilities to generate the non-zero elements of a system matrix and to read and write such data to disk in cross-language binary form.

If n is the number of transducers per probe, non-zero elements of a system matrix are stored in an nxn Array of type `Any`, a structure roughly equivalent to a cell array in Matlab or Octave. Entry i,j of this array identifies the pixels crossed by the path from transmitter i to receiver j, and gives the lengths intersected with each. This entry is a 1x2 array of type `Any` whose first component is an array of pixel indices, and whose second is the corresponding lengths.
"""
module GenS

export wCrossings, gridCrossings, segmentLengths, probePos, genS, writeSData, readSData, readCell, writeCell


"""
wCrossings(u, v, w, k)
    
Given three vectors, u, v, w, and a series of scalars, k, find all lambda in the 
unit interval such that the inner product of w with u + lambda*(v-u) is one of the
scalars in k.
"""
function wCrossings(u::Array{Float64,1}, v::Array{Float64,1}, w::Array{Float64,1}, k::Array{Float64,1})
    lambda =  (k - dot(u,w))/dot(v-u,w);
    return lambda[0.0 .<= lambda .<= 1.0];
end

"""
gridCrossings(u, v, width, height, gridsize, [epsilon])

Find the points of a 2D grid crossed by a line segment whose two endpoints are u and v.
The grid is defined by an integral height and width and a gridsize. Its lower left
corner is assumed to be the origin. Pixels are assumed to be square and grid lines
are assumed parallel to the x and y axes. Width refers to the number of cells in the
x direction, height to those in the y direction. Returned crossings will be in order from u to v.
"""
function gridCrossings(u::Array{Float64,1}, v::Array{Float64,1}, width::Int, height::Int,
                       gridsize::Float64, epsilon = (eps(Float64)^.75))
    kx = collect(gridsize*(0:width)); # collect converts Range object to Array
    ky = collect(gridsize*(0:height));
    lambda = sort(unique(vcat(wCrossings(u,v,vcat(1.0,0.0), kx), wCrossings(u, v, vcat(0.0,1.0), ky))));
    # Since lambdas are sorted in ascending order, crossings will be
    # in order from u to v. Eliminate any which are too close together.
    n = length(lambda);
    if n > 1
        idx = vcat(true, abs(lambda[1:(n-1)]-lambda[2:n]) .> epsilon);
    elseif n == 1
        idx = vcat(true);
    else
        return Array(Float64,0,2)
    end
    crossings = hcat(u[1] + lambda[idx]*(v[1]-u[1]),
                     u[2] + lambda[idx]*(v[2]-u[2]));
    return crossings
end

"""
segmentLenghts(u, v, width, height, gridsize)
    
Given a line segment determined by 2 endpoints, u and v, and 2D grid determined
by a width, height, and gridsize, return the indices of the pixels crossed
and the lengths of their intersections with the segment. Return value is
a tuple: indices, lengths.
"""
function segmentLengths(u::Array{Float64,1}, v::Array{Float64,1}, width::Int, height::Int, gridsize::Float64)
    crossings = gridCrossings(u, v, width, height, gridsize);
    n = size(crossings,1);
    if n > 1
        return 1+floor(Int, (crossings[1:(n-1),:]+crossings[2:n,:])/(2*gridsize)), # indices
        sqrt((crossings[2:n,:]-crossings[1:(n-1),:]).^2 * vcat(1,1));   # lengths
    else
        return Array(int,0,2), Array(Float64,0,1);
    end
end


"""
transducerPos(n, u, v)
    
Given a number, n, of equally spaced transducers and two points, u and v, representing
the two endpoints of a probe, return transducer positions as an n by 2 matrix.<commit_msg>File CreateSMatrix.jl to create S matrices from genS output<commit_after>"""
module GenS

Utilities to generate the non-zero elements of a system matrix and to read and write such data to disk in cross-language binary form.

If n is the number of transducers per probe, non-zero elements of a system matrix are stored in an nxn Array of type `Any`, a structure roughly equivalent to a cell array in Matlab or Octave. Entry i,j of this array identifies the pixels crossed by the path from transmitter i to receiver j, and gives the lengths intersected with each. This entry is a 1x2 array of type `Any` whose first component is an array of pixel indices, and whose second is the corresponding lengths.
"""
module GenS

include("CreateSMatrix.jl")

export wCrossings, gridCrossings, segmentLengths, probePos, genS, writeSData, readSData, readCell, writeCell, createSMatrix, createSparseS


"""
wCrossings(u, v, w, k)
    
Given three vectors, u, v, w, and a series of scalars, k, find all lambda in the 
unit interval such that the inner product of w with u + lambda*(v-u) is one of the
scalars in k.
"""
function wCrossings(u::Array{Float64,1}, v::Array{Float64,1}, w::Array{Float64,1}, k::Array{Float64,1})
    lambda =  (k - dot(u,w))/dot(v-u,w);
    return lambda[0.0 .<= lambda .<= 1.0];
end

"""
gridCrossings(u, v, width, height, gridsize, [epsilon])

Find the points of a 2D grid crossed by a line segment whose two endpoints are u and v.
The grid is defined by an integral height and width and a gridsize. Its lower left
corner is assumed to be the origin. Pixels are assumed to be square and grid lines
are assumed parallel to the x and y axes. Width refers to the number of cells in the
x direction, height to those in the y direction. Returned crossings will be in order from u to v.
"""
function gridCrossings(u::Array{Float64,1}, v::Array{Float64,1}, width::Int, height::Int,
                       gridsize::Float64, epsilon = (eps(Float64)^.75))
    kx = collect(gridsize*(0:width)); # collect converts Range object to Array
    ky = collect(gridsize*(0:height));
    lambda = sort(unique(vcat(wCrossings(u,v,vcat(1.0,0.0), kx), wCrossings(u, v, vcat(0.0,1.0), ky))));
    # Since lambdas are sorted in ascending order, crossings will be
    # in order from u to v. Eliminate any which are too close together.
    n = length(lambda);
    if n > 1
        idx = vcat(true, abs(lambda[1:(n-1)]-lambda[2:n]) .> epsilon);
    elseif n == 1
        idx = vcat(true);
    else
        return Array(Float64,0,2)
    end
    crossings = hcat(u[1] + lambda[idx]*(v[1]-u[1]),
                     u[2] + lambda[idx]*(v[2]-u[2]));
    return crossings
end

"""
segmentLengths(u, v, width, height, gridsize)
    
Given a line segment determined by 2 endpoints, u and v, and 2D grid determined
by a width, height, and gridsize, return the indices of the pixels crossed
and the lengths of their intersections with the segment. Return value is
a tuple: indices, lengths.
"""
function segmentLengths(u::Array{Float64,1}, v::Array{Float64,1}, width::Int, height::Int, gridsize::Float64)
    crossings = gridCrossings(u, v, width, height, gridsize);
    n = size(crossings,1);
    if n > 1
        return 1+floor(Int, (crossings[1:(n-1),:]+crossings[2:n,:])/(2*gridsize)), # indices
        sqrt((crossings[2:n,:]-crossings[1:(n-1),:]).^2 * vcat(1,1));   # lengths
    else
        return Array(int,0,2), Array(Float64,0,1);
    end
end


"""
transducerPos(n, u, v)
    
Given a number, n, of equally spaced transducers and two points, u and v, representing
the two endpoints of a probe, return transducer positions as an n by 2 matrix.
{'fraction_non_alphanumeric': 0.11426176840340829, 'fraction_numerical': 0.024025701913675094, 'mean_word_length': 3.854237288135593, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7336561', 'n_tokens_mistral': 2364, 'n_tokens_neox': 2247, 'n_words': 924}