New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consolidate / Simplify factor evaluation (CalcFactor) #467
Comments
cc @Affie |
EDIT, DF this parametric only API is being deprecated/removed. Ok to implement cost directly function (s::LinearConditional)(X1::Vector{Float64},
X2::Vector{Float64};
userdata::Union{Nothing,FactorMetadata}=nothing)
# getFactorMean(s)
meas = s.Z.μ
# getFactorCov(s)
σ = s.Z.σ
res = [meas - (X2[1] - X1[1])]
return (res/σ) .^ 2
end |
Unfortunately i don't think we should re-implement the costs as duplicates -- okay for dev just to get started, but would rather do this with a wrapper over the existing factor definitions. I can help with that and is on my TODO list. In the mean time see common reference here: |
I've temporary continued with the re-implementing approach for simplicity. |
We can sort out the wrappers for dual nonparametric parametric use in IIF EDITED |
will resolve this after #459 is completed. Only down message consolidation remains at this point. |
FMD refactor must be completed first EDIT: roughly speaking, see #1025 |
Hi @Affie , thanks -- there is a lot to unpack here. Think this is in the right ball park with some good but maybe a few pieces of this may have to change... I want to be very careful about communicating accurately here else we going to go around in circles. Give me a few hours to write clear (so-called "counter") examples.
This is the part I'm most worried about (big 'no' from me unless you mean something specific). Lets make sure we are talking the same language here and forthcoming "counter" examples is probably best -- stay tuned... |
N.B. this a pointed technical discussion to try understand a far reaching multiple-dispatch issue -- no harm intended. I don't know if any other hard-typed parametric and nonparametric libraries exist that can do both styles of inference using exactly the same member definitions as we are doing here. ( The issue at hand is to use standard Julia autodiff tools while maintaining statically typed functions for all run-time, user defined factor types, including automated blends of Never do thisfunction (s::CalcFactor)(variables...)
s.res .= s.factor(variables...)
return sum(s.resl.^2)
end or # then the default call for CalcFactor for non-parametric
function (s::CalcFactor)(variables...)
s.res .= s.factor(variables...)
nothing
end Specifically the part #The easy/basic factor function definitions
function (s__::LinearRelative)(z,x1,x2)
res = z - (x2 - x1)
end Because it is super important that users learn / use only ONE SINGLE API definition that works for all cases, that is Also remember there are also years of pain baked into Notice that the existing code forces us to use both NLsolve.jl and Optim.jl, which allows both Okay, so @Affie are you saying that this is not a workable solution for consolidated ("Malahanobis distance") evaluation?
Should Standardize to Only This#The standard factor function definition template
function (s::CalcFactor{<:MyFactor})(measurements..., variables...)
# maybe you need other stuff...
# t1 = getTimestamp(s.metadata.dfgVariable[1])
# maybe inline fails and you can avoid memory allocations by reusing
# s.residual[1] = ... # some compute A
# or you directly use your own internal
res1 = ... # some compute A
res2 = ... # more compute B
# alternatively user is forcing in-place and does, return s.residual
return [res1; res2]
end This means we would do something like: (s::CalcFactor{<:LinearRelative})(z,x1,x2) = z - (x2 - x1) I really do not see a problem with using this later as a simple single standard that works for all known use-cases. Are you saying @Affie there is absolutely no way in which you can get the type-stable dispatch to work (including todays fix #1138 ) using this later definition for both nonparametric and parametric? Parametric should then be able to just use this for Malahanobis distance calculations (can do pseudo-Huber cost function, etc. later): IncrementalInference.jl/src/ParametricUtils.jl Lines 103 to 106 in d06fe4c
Also remember we will also do max-mixtures by consolidating parametric with Finally, IIF v0.21.0 will likely again bring a breaking change on factor residual API, so that the residual function always returns |
The "returning residual" way
Not at all, this is the quickest and easiest way to get type stability, leave it up to julia to figure out the return type. I'm 100% happy with it. I started implementing it but got stuck on non-parametric that calls the function with the residual as a parameter and the difference that is then required between Minimize and Roots (as far as I understand). The "never do this" wayI'm not sure I follow your answer and if my example was clear enough, but it will break your ONE SINGLE API rule for factor definitions as there will be one for the simple (<:FunctorInferenceType) and one for complex (<:CalcFactor{<:FunctorInferenceType}) factor types. |
Perhaps we can get away with #1140. It still requires proper testing in RoME though. |
That's great so we have consensus on that part! I strongly agree with |
I think I follow your example and if so, I'm trying to stop you from going down the path of creating an "easy" and "complex" interface. I am very strongly against that idea. Thats what I meant with "never do this way". (Going back at least 14 months, #467 (comment))
This is what I'm trying to avoid and stop. Let me look at 1140 and see if I can say anything more useful. But just note, at this stage I would not merge anything on factors that breaks the "one API only requirement". |
With #1140 as a 'towards' consolidation it looks fine. I know the experimental parametric factor definitions follow the "easy" interface that still excludes the new To illustrate again, I really cannot see what the 'complexity' is with a definition like this (and note this does satisfy the "one api requirement"): (s::CalcFactor{<:LinearRelative})(z, x1,x2) = z - (x2 - x1) |
Just to be clear, we have a project wide requirement that there should be just one API for residual factor evaluation. In the future there will be multiple algorithms and our history of using these factors in different applications FORCES us to create the headroom via This one API is now definitely an absolute requirement for the foreseeable future. Sorry for pushing so hard on this, but let's just get it done and keep moving. EDIT, added this to the high level requirements list: |
I just wrote down an idea to enable factor reuse. It would still all be |
Regarding #1140, I merged it as it can use The next step with parametric is to update RoME for Parametric CalcFactor and properly test it with #1140. We should decide if factors should return residual or change parameter and return nothing.
|
ping @Affie
Sorry if that has not been clear. Yes please always return the residual for both Roots and Minimize. Following from our discussions, this sounds like the best direction for new single API for factor residual functions (to solve dispatch on autodiff). And we are removing
I doubt this will hold for very long, but lets get the consolidation done on actual functions and then worry about generalizing residual type for more cases. The main task item right now is droping two factor definitions between different algorithms, down to only the one single API usage. |
Hi @Affie , thanks for all the effort and 1147 -- think we can close this issue now right? |
I just want to do this before closing:
But, yes it can be closed, just want to keep track of whats outstanding. |
EDITED (20Q4 / 21Q1):
Using this issue for topics related to consolidating the nonparametric and parametric factor residual function API. Idea is user writes one residual factor in a sensible way, and IIF is able to use that factor for both parametric and nonparametric with little to no change from the user perspective. A critical point to note here is that nonparametric (nonGaussian) is much more versatile and general, so there are many many cases where parametric will just not be possible -- regardless the API should be standardized.
References:
IIF.getSample
standardize special sampler using new FMd / CalcResidual #927Current holdups:
AbstractRelativeMinimize
should returnresidual::Vector
, not self accumulate to a Real scalar value.New Documentation
Preliminary New API Example
IncrementalInference.jl/src/Factors/LinearRelative.jl
Lines 42 to 51 in 0469062
Parametric Integration Work 90% (?) Done
DF, I was hoping to just finish the consolidation with (#467 (comment)) but alas! Note that much of the consolidation work has already been done surrounding
_CalcFactorParametric
as the internal interface between newCalcFactor
API andsolve__Parametric
functions. E.g. see:IncrementalInference.jl/src/ParametricUtils.jl
Lines 81 to 90 in 9e225b7
Original Issue Question
How would you use a normal IIF factor in parametric? example.
The text was updated successfully, but these errors were encountered: