niessner / Opt

Opt DSL
Other
256 stars 68 forks source link

Multidimensional graphs in Opt #87

Closed lotmennikov closed 7 years ago

lotmennikov commented 7 years ago

Hi, I want to ask if it is possible to express graphs that map nodes in one dimension to nodes in another dimension, like this: local W = Dim("W", 0) local N = Dim("N", 1) local v = Array("v", opt_float3, { W }, 0) local vt = Array("vt", opt_float3, { W }, 1) local x = Unknown("x", opt_float3, { N }, 2) local G = Graph("G", 3, "v0", { W }, 4, "v1", { N }, 5) Suppose the first dimension is a set of points and the second is a set of offsets, where each offset influences several points. Each edge connects one point to one offset. I've tried to run it, but the only thing opt does correctly is cost estimation. If I use one offset per point without graphs, it works fine. From the previous issues it seems to be possible, but in all provided Opt examples dimensions in graphs are the same. BTW, what is the difference between types "float3" and "opt_float3"?

Mx7f commented 7 years ago

Yes, that works. If you have a particular example where it does not we can try and track down what is going wrong.

"opt_float3" will be equivalent to "float3" if Opt_InitializationParameters.doublePrecision is false. Otherwise it is equivalent to "double3".

lotmennikov commented 7 years ago

I've tried this code with graph and different dimensions: local function norm(v) return sqrt(v(0)*v(0)+v(1)*v(1)+v(2)*v(2)) end local e_data = norm(v(G.v0) + x(G.v1) - vt(G.v0)) Energy(e_data) and this code without graph and equal dimensions:

local W = Dim("W", 0) local v = Array("v", opt_float3, { W }, 0) local vt = Array("vt", opt_float3, { W }, 1) local x = Unknown("x", opt_float3, { W }, 2) local function norm(v) return sqrt(v(0)*v(0)+v(1)*v(1)+v(2)*v(2)) end local e_data = norm(v(0) + x(0) - vt(0)) Energy(e_data)

VT is just a set of 3d points and V is the same set with some translation (equal for all points in my test). In the first case there is a graph connecting each point with some translation X (I've tried N=1 (all points connected to one X) and N=W (one X per point)). In the second case there is just one X per point. The second program works, the first one only gives final cost equal to the initial cost, unknowns are unchanged.

Mx7f commented 7 years ago

I can set up a test case tomorrow, in the meantime, can you confirm you are on the latest commit, and then set your Opt_InitializationParameters.verbosityLevel to 2 and send the output?

lotmennikov commented 7 years ago

Updated to the last commit, there are some occasional lines from my code in the output: log.txt

Also, if I add some constraint for unknowns like Energy(x(0)), it works.

upd: I changed energy function to local e_data = v(G.v0) + x(G.v1) - vt(G.v0) accidentally, here is output for norm(...): log2.txt

Mx7f commented 7 years ago

Sorry for the late response.

Yes, there seems to be an error when there are no unknown-wise residual terms. I will work on a fix but in the meantime you can work around it by adding a zero-valued energy term that does not get optimized away by:

-- Hack to get example to work with no image domain energy
    local zeroIm = ComputedImage("zero",{W},0.0)
    local sumOfParams = x(0)(0) + x(0)(1) + x(0)(2)
    Energy(zeroIm(0)*sumOfParams)
Mx7f commented 7 years ago

The original bug has been fixed, see #91.

lotmennikov commented 7 years ago

I actually didn't really want to use only graph energies, that was just a test. But now I see I'm not the only one who had this problem. Thank you!