vshesh

vshesh

Nx.LinAlg.solve basic case error?

Trying to implement projective transform in elixir.
I ported an algorithm over from another project:

defmodule ProjectiveTransform do
  def make_transform(
    [[x1, y1], [x2, y2], [x3, y3], [x4, y4]],
    [[xx1, yy1], [xx2, yy2], [xx3, yy3], [xx4, yy4]]
  ) do
    make_transform(
      [x1, y1, x2, y2, x3, y3, x4, y4],
      [xx1, yy1, xx2, yy2, xx3, yy3, xx4, yy4])
  end
  def make_transform(
    [x1, y1, x2, y2, x3, y3, x4, y4],
    [xx1, yy1, xx2, yy2, xx3, yy3, xx4, yy4]
  ) do
    a = Nx.tensor([
      [x1, y1, 1, 0, 0, 0, 0, 0,   -xx1, 0, 0, 0],
      [x2, y2, 1, 0, 0, 0, 0, 0,   0 ,-xx2, 0, 0],
      [x3, y3, 1, 0, 0, 0, 0, 0,   0, 0 ,-xx3, 0],
      [x4, y4, 1, 0, 0, 0, 0, 0,   0, 0, 0 ,-xx4],
      [0, 0, 0, x1, y1, 1, 0, 0,   -yy1, 0, 0, 0],
      [0, 0, 0, x2, y2, 1, 0, 0,   0 ,-yy2, 0, 0],
      [0, 0, 0, x3, y3, 1, 0, 0,   0, 0 ,-yy3, 0],
      [0, 0, 0, x4, y4, 1, 0, 0,   0, 0, 0 ,-yy4],
      [0, 0, 0, 0, 0, 0, x1, y1,    -1, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, x2, y2,   0  ,-1, 0, 0],
      [0, 0, 0, 0, 0, 0, x3, y3,   0, 0  ,-1, 0],
      [0, 0, 0, 0, 0, 0, x4, y4,   0, 0, 0  ,-1],
    ])
    v = Nx.tensor([0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1])
    x = Nx.LinAlg.solve(a, v)
    Nx.reshape(Nx.concatenate([x[0..7], Nx.tensor([1])]), {3,3})
  end
end

Then wrote a simple test


defmodule ProjectiveTransformTest do
  use ExUnit.Case, async: true
  use ExUnitProperties

  alias StreamData
  import TestHelpers

  test "single hardcoded transformation case" do
    assert ProjectiveTransform.make_transform(
      [[0,0], [0,10], [10,10], [10,0]],
      [[0,0], [0,10], [10,10], [10,0]]
    ) == Nx.eye(3)
  end
end

And when I run mix test I get the following error:


  2) test single hardcoded transformation case (ProjectiveTransformTest)
     test/object_tracking_test.exs:57
     Assertion with == failed
     code:  assert ProjectiveTransform.make_transform([[0, 0], [0, 10], ~c"\n\n", [10, 0]], [
              [0, 0],
              [0, 10],
              ~c"\n\n",
              [10, 0]
            ]) == Nx.eye(3)
     left:  #Nx.Tensor<\n  f32[3][3]\n  [\n    [1.0000011920928955, -2.006071753157812e-7, 1.415989459019329e-6],\n    [9.025153069330827e-9, 1.000001072883606, -2.960541394259053e-7],\n    [8.9426798410841e-8, 5.948747983097746e-8, 1.0]\n  ]\n>
     right: #Nx.Tensor<\n  s64[3][3]\n  [\n    [1, 0, 0],\n    [0, 1, 0],\n    [0, 0, 1]\n  ]\n>

For comparison, the same exact thing in Julia:

julia> make_perspective(((0,0), (0,10), (10,10), (10,0)), ((0,0), (0,10), (10,10), (10,0)))
3×3 SMatrix{3, 3, Float64, 9} with indices SOneTo(3)×SOneTo(3):
 1.0  0.0  0.0
 0.0  1.0  0.0
 0.0  0.0  1.0

It looks like it’s “close” to zero but why e-7?

Most Liked

polvalente

polvalente

Nx Core Team

There are 2 issues at hand here. Firstly, your equality check is going to fail because you’re comparing an s64 tensor to an f32 tensor, and those will always be different Elixir-wise.

Nx unit tests use an assert_equal helper that you can yank, or better yet, assert all close.

Now for the precision issue. You’re dealing with floating point numbers, and the first difference I spot is that in Julia you used f64, while in Nx you used f32. That by itself is already a source of significant difference. Aside that, Julia might be doing some rounding in the results, especially in the underlying mechanisms of the linear system solution (e.g zero-rounding in PLU or QR decomposition before doing triangular solves)

Where Next?

Popular in Questions Top

Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New

Other popular topics Top

rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 54092 488
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 54996 245
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New

We're in Beta

About us Mission Statement