I think, I can now better articulate a problem I have with Nx.conv.
# Define the two time series
t1 = np.array([0.1, 0.2, 0.4, 0.7, 0.9, 0.8, 0.6, 0.3, 0.1])
t2 = np.array([0.3, 0.6, 0.8, 0.7, 0.4, 0.2, 0.1, 0.1, 0.3])
In Nx I added |> Nx.reshape({1, 1, 9})
I just compared the results from Numpy and Nx:
|
correlate |
convolve |
Numpy |
1.6 |
1.84 |
Nx |
Nx.conv(Nx.reverse(t1, t2) |
Nx.conv(t1, t2) |
|
1.84 |
1.6 |
Should is that correct? Should I open a ticket?
I updated my implemention. Because I had some problem with Nx. I used more standard Elixir.
defmodule CrossCorrelation do
def cross_corr(t1, t2) do
Nx.conv(t1, t2)
end
def full_cross_corr(t1, t2) do
l1 = elem(Nx.shape(t1), 2) - 1
indices1 = 0 .. l1
coeff1 =
Enum.map(indices1, fn x ->
ts1 = t1[[.., .., 0..x]]
ts2 = t2[[.., .., 0..x]]
Nx.to_number(Nx.conv(ts1, ts2)[0][0][0])
end)
indices2 = 1..l1
coeff2 =
Enum.map(indices2, fn x ->
ts1 = t1[[.., .., x..-1//1]]
ts2 = t2[[.., .., x..-1//1]]
Nx.to_number(Nx.conv(ts1, ts2)[0][0][0])
end)
coeff1 ++ coeff2
end
def find_offset(t1, t2) do
l1 = elem(Nx.shape(t1), 2)
coeffs = full_cross_corr(t1, t2)
Nx.argmax(Nx.tensor(coeffs))
Nx.to_number(Nx.argmax(Nx.tensor(coeffs))) - l1 + 1
end
end
Problem I have is: that the result is good when compare the simple autocorrelation with the Tensor [[[1, 2, 3, 4, 5]]]. CrossCorrelation.full_cross_corr
compares good to numpy.correlate(t1, t2, mode=full)
. But for the more realistic, time series t1 and t2. The result differs greatly.
I do not know, whether I did something wrong, or its something different. There is not something similar to numpy.correlate(t1, t2, mode=full)
yet in Nx, right?
P.S.: We wrote at the same time. I added some links the table.
I also wanted to add some test results:
numpy:
cross_corr = np.correlate(t1, t2, mode='full')
Returns:
0.03,0.07,0.15,0.29000000000000004,0.46,0.6300000000000001,0.8699999999999999,1.1900000000000002,1.6,1.9699999999999998,2.1300000000000003,1.9500000000000002,1.48,0.9099999999999999,0.44,0.15,0.03
My Elixir implementation:
def full_cross_corr(t1, t2) do
l1 = elem(Nx.shape(t1), 2) - 1
indices1 = 0 .. l1
coeff1 =
Enum.map(indices1, fn x ->
ts1 = t1[[.., .., 0..x]]
ts2 = t2[[.., .., 0..x]]
Nx.to_number(Nx.conv(ts1, ts2)[0][0][0])
end)
indices2 = 1..l1
coeff2 =
Enum.map(indices2, fn x ->
ts1 = t1[[.., .., x..-1//1]]
ts2 = t2[[.., .., x..-1//1]]
Nx.to_number(Nx.conv(ts1, ts2)[0][0][0])
end)
coeff1 ++ coeff2
end
returns:
[0.030000001192092896, 0.15000000596046448, 0.4700000286102295, 0.9600000381469727,
1.3200000524520874, 1.4800000190734863, 1.5399999618530273, 1.5699999332427979, 1.600000023841858,
1.5699999332427979, 1.4500000476837158, 1.1299999952316284, 0.6399999856948853, 0.2800000309944153,
0.12000000476837158, 0.06000000238418579, 0.030000001192092896]