Open yakir12 opened 5 years ago
Can you give me a simple example?
So while this works:
julia> optimize(x -> abs(sin(x) - 0.5), 0.1, 1)
Results of Optimization Algorithm
* Algorithm: Brent's Method
* Search Interval: [0.100000, 1.000000]
* Minimizer: 5.235988e-01
* Minimum: 1.156697e-09
* Iterations: 26
* Convergence: max(|x - x_upper|, |x - x_lower|) <= 2*(1.5e-08*|x|+2.2e-16): true
* Objective Function Calls: 27
This doesn't:
julia> optimize(x -> abs(sin(x) - 0.5), 0.1rad, 1rad)
ERROR: MethodError: no method matching optimize(::getfield(Main, Symbol("##591#592")), ::Quantity{Float64,Unitful.Dimensions{()},Unitful.FreeUnits{(Unitful.Unit{:Radian,Unitful.Dimensions{()}}(0, 1//1),),Unitful.Dimensions{()}}}, ::Quantity{Int64,Unitful.Dimensions{()},Unitful.FreeUnits{(Unitful.Unit{:Radian,Unitful.Dimensions{()}}(0, 1//1),),Unitful.Dimensions{()}}})
Closest candidates are:
optimize(::Any, ::Any, ::Any, ::AbstractArray; inplace, autodiff, kwargs...) at /home/yakir/.julia/packages/Optim/ULNLZ/src/multivariate/optimize/interface.jl:76
optimize(::Any, ::Any, ::Any, ::AbstractArray, ::Optim.Options; inplace, autodiff) at /home/yakir/.julia/packages/Optim/ULNLZ/src/multivariate/optimize/interface.jl:103
optimize(::Any, ::Any, ::Any, ::AbstractArray{T,N} where N, ::Optim.AbstractOptimizer) where T at /home/yakir/.julia/packages/Optim/ULNLZ/src/multivariate/optimize/interface.jl:126
...
Stacktrace:
[1] top-level scope at none:0
Just a general but relevant comment: I'm in the process of allowing my own package to accept units and I have to say, while it was a great experience and helped me identify a few key concepts that I hadn't thought of, the benefit versus the pain (and speed penalty) has been meh. In my own case, allowing for units has fallen into a GUI category. Yes I can allow for them, but the user could solve that on their end very easily. So there's no real intrinsic reason for my package to allow for units (especially since there are only Length ones). So having said that... Consider this issue as you wish, I'm slowly backing out from adding unit-functionality to everything. If nothing else, this is a telling indicator that adding units is a lot harder than I had hoped.
There shouldn't be a speed penalty at all? Even when using them, it's all just in the type-system. But I agree setting up code to use units is difficult since you actually have to think about units and everything needs to satisfy dimensional analysis.
you actually have to think about units and everything needs to satisfy dimensional analysis.
That's the part I like. It improves the code. What I miss is this magical, easy, straightforward process of taking a package who's types accept all manners of AbstractFloat
s while keeping concrete and allowing it to accept units, while still keeping concrete (so no types are abstract). But I might have missed some trick to how to do it.
So just to be clear, my speed penalty is not due to Unitful but more due to how I integrated it in my code.
Keeping things abstract doesn't have a speed penalty. Types just need type parameters.
Types just need type parameters.
To me, with units, this can get a bit elaborate.
I've also hit this problem. Optim should work with units.
I've also hit this problem.
What are you trying to do? What's your objective, what methods are you using, ...?
Optim should work with units.
PRs welcome :)
I think it's fair to say that the current version of Optim will not support this in any significant manner. It ties together with some of the design issues Optim and related packages have, but I'm working on a new version of optim that shouldn't have these issues.
It's not a big deal, I just got the complaint from a coworker that adding units broke optim in one of my packages... And I can't think of why they shouldn't work theoretically (of course in practice it's more difficult). This is just a +1 to units working in future.
It's good to know you are working on a new version!
I'm working on a new version of optim that shouldn't have these issues.
Any update on that version that might support units?
I've been thinking about this for my work on image reconstruction. Here's a concrete example. In X-ray CT the image should have units of 1/cm (linear attenuation coefficient) so the argument of the cost function f(x)
is an array where all elements have the same units (1/cm) and typically the cost function is unitless.
The delicate part is that then the gradient of f
has units (1/(1/cm) = cm, so to implement an in-place gradient g!(G, x)
the preallocated array G
must have the reciprocal units of x
(or do a lot of fussing with reinterpret
) so I can't just do the usual G = similar(x)
. It's all solvable in principle and I actually like having to think this through, leading to things like G = similar(x, typeof(1 / oneunit(x)))
. But if @pkofod has already worked all this out in another package I'd rather not reinvent the wheel.
In machine learning where a data vector x
might have different features with different units (height, weight, IQ, etc.), it seems to get much more complicated and I'm not going to attempt that case. Supporting argmin_x f(x)
where all elements of x
have the same units would be quite useful.
Is it possible (without loosing performance/functionality)?