-
Notifications
You must be signed in to change notification settings - Fork 37
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
Is Measurements.jl compatible with Optim.jl and ForwardDiff.jl, or am I facing a gotcha? #100
Comments
I'm aware of some issues with Optim.jl, but due to a bug in that package: JuliaNLSolvers/Optim.jl#823. I believe Measurements.jl can't work with ForwardDiff because of the limitations of the latter package. In the end, I don't think there is anything I can do here |
Can't believe I missed that post in the Optim page! Thanks for pointing this out! It's helpful as it tells me that this is a fundamental bug and not something I'm doing incorrectly when feeding it in. For anyone else struggling with this: I'm attempting the following workaround (as long as your main case allows for analytical solutions that work with Measurements.jl)
|
@giordano A few of us from the Humans of Julia discord noticed that the line 92 in Measurements.jl/src/Measurements.jl Line 92 in 287f575
When using ERROR: LoadError: StackOverflowError:
Stacktrace:
[1] measurement(val::ForwardDiff.Dual{ForwardDiff.Tag{Main.PengRobinson.PRVolumeSolver.var"#target_function#1"{StaticArrays.SVector{2, Main.PengRobinson.PengRobinsonChemical{Float64, Float64, Float64, Float64, Float64}}, StaticArrays.SVector{2, Measurement{Float64}}, StaticArrays.SMatrix{2, 2, Float64, 4}, Float64, Float64, Measurement{Float64}}, Float64}, Float64, 1}, err::ForwardDiff.Dual{ForwardDiff.Tag{Main.PengRobinson.PRVolumeSolver.var"#target_function#1"{StaticArrays.SVector{2, Main.PengRobinson.PengRobinsonChemical{Float64, Float64, Float64, Float64, Float64}}, StaticArrays.SVector{2, Measurement{Float64}}, StaticArrays.SMatrix{2, 2, Float64, 4}, Float64, Float64, Measurement{Float64}}, Float64}, Float64, 1}) (repeats 79984 times)
@ Measurements ~\.julia\dev\Measurements\src\Measurements.jl:92
in expression starting at c:\git\julia-polymer-membranes\PolymerMembranes.jl\test.jl:30 In the case that you use Optim.jl's finite differencing, the issue doesn't occur, so it seems the issue is that line calling itself until the Stack Overflow Error happens. If you want to know more about what I was doing / talk to us over at HoJ, I'm more than happy to explain it! |
That's not the problem, the culprit is ForwardDiff being unable to deal with anything more specific than
But |
That's completely understandable, and thanks for the quick responses! So far, it seems that using Optim.jl while breaking the components into uncertainties and values and solving them independently works well, do you have any advice about how I might go about splitting a measurement object into this without running into issues? Applying the same technique to other optimization libraries like BlackBoxOptim.jl, which (shouldn't) do any autodiff-like things with the functions creates very strange results. There, the same stackoverflow issue happens without even doing anything other than just using BlackBoxOptim
# using Measurements # uncomment this after confirming it runs correctly
function solve_volume_uncertainty_bbox(p_uncertainty, v_value, t)
function target_function(volume_uncertainty_guess_l_mol)
resulting_pressure = 4
return (resulting_pressure - p_uncertainty)^2
end
res = bboptimize(target_function; SearchRange=(0.0, 10.0), NumDimensions=1, Method=:de_rand_1_bin)
return best_candidate(res)[1]
end
bbox = solve_volume_uncertainty_bbox(0.1, 20.08405, 273.15)
println(bbox) It may also just be something that happens on my machine. I'm hoping that this might prove useful to you in some way, because I'm super excited that this library exists. In my field, errors are basically unseen in most literature (I'm planning on citing your library in mine as well, once I get my underlying calculations working!), as its too lengthy to do the analytical calculations by hand. The ultimate version of this would be to somehow generally extend it to optimization as well as direct or, for the lack of a better word: analytical as opposed to iterative, solutions are only a subset of the calculations done. |
That's extremely bizarre, but since |
BTW, in JuliaNLSolvers/Optim.jl#823 I had some suggestions about how to fix |
For the record, Lines 619 to 622 in e71f520
but frankly I don't see how that would be relevant since it isn't called at all in your example. |
Thanks @giordano! This is extremely helpful, how did you track down the BlackBoxOptim.jl issue to those lines? I was never quite able to narrow it down further than things happening in my own code. This was mainly because the stackoverflow error caused by importing I'll send it over to them and see if they'd be willing to work on it! Ideally we'd have at least one optimization library that works without tomfoolery in |
Binary search: I commented half of the code of |
Whelp, I'm adding that to my bag of tricks. Thanks again! |
ok, im trying to make optim work with measurements, and the main show problem comes on the use of the @sprintf macro for printing |
Forgive me for etiquette and formatting issues, this is my first real github issue post. Further, if this wasn't the appropriate place to post problems like this, please let me know.
What I'm trying to do
I'm trying to optimize a function that has error associated with it.
I'm aware there is not a meaningful way to propagate error through the optimization process out-of-the-box, as we're guessing with a pure number, but my strategy would be to optimize twice: Once for the actual value, and a second time to arrive at the same error as the target variable. I'm running into some very strange issues when trying to accomplish the former, however, and cannot tell if it is due to my being new to Julia, or something fundamental to one of the packages involved.
Tl,dr: For all intents and purposes, right now I'm just trying to optimize a pure number, where Measurement.jl types might be fed in as well. I don't care if errors aren't propagated correctly in this case, I just want this to happen without errors i.e., I want ForwardDiff and Measurement types to play nice.
The nature of the problem (context)
The code in question right now is a struct capable of solving one of the three following variables, given the other two: P, V, and T.
e.g., if P and T are specified, V is solvable
If V and T are specified, then solving P is an analytical problem (and thus does not need Optim.jl), right now Measurements works wonderfully in this case.
If P and T are specified, we need to guess V until we minimize the loss function: (P_calculated - P_given)^2. This is done with Optim.jl and using automatic differentiation. I've also tried using finite differencing. This is where Measurements.jl (or something else) seems to fail.
Errors and information
When feeding a function into Optim.jl where any variable involved is a Measurement type, the following type of ambiguity errors occur with simple arithmetic methods:
If we instead forego automatic differentiation, and have Optim.jl try to use a function containing any measurement type with finite differencing, we arrive at
And this last error seems to be something that is more my fault than anything else. However, it isn't traced back to my own code, but rather something in Optim.jl. The full stack trace for this is below:
I was going to provide a minimum working example but it turned out to be a bit too hefty to post here, if this issue is truly a potential compatibility problem with Measurements and someone needs to reproduce this easily, please run
test.jl
in this repo and be sure to add the measurement syntactic sugar somewhere to cause the error (otherwise it will work!) in one of the constructor methods.The text was updated successfully, but these errors were encountered: