Replies: 6 comments
-
Apologies for the late reply and thanks for the kind words! argmin does not know anything about your For Why do you want your own structs? Typically one would resort to using one of the math backends. If you need to carry around additional data you may be better off moving it to the problem struct. |
Beta Was this translation helpful? Give feedback.
-
Not a problem! Totally reasonable time for a reply :) That all makes sense, I think my surprise comes from where those trait bounds are applied. As I was following along in examples, I was implementing I see now that if needed, I could implement the math-related traits for any struct that I wanted. So to reframe the discussion, I am asking if there is some way for those trait bounds to be applied to the various traits that we implement for our problem structs as well as the solvers. This way, I know my implementation of a problem will work with at least some solvers. I think the difficulty comes because the solvers do not require the same trait bonds (I assume). Is there a common trait among them all, for example the output is If it is not possible to constrain the types, I think a mention in the Book that the traits we implement for the problem are then restricted by the solver we choose, so we should look at those details before implementing the problem so we don't have type conflicts later on that surprise us. |
Beta Was this translation helpful? Give feedback.
-
That makes absolutely sense!
That's correct. Different solvers have different requirements.
No, there is no supertrait (I think that's what they are called, but I'm not sure). Do I understand correctly that you are asking for a trait which covers all math-related traits, and as such can be used to constrain for instance This has substantial downsides, in particular with the wider ecosystem:
I personally think the fact that only the solver defines which traits must be implemented is a good design. For instance, if you want to use a custom type and you're only interested in L-BFGS, then you only need to implement the traits which are really needed. Now back to your problem. Assuming you are using the |
Beta Was this translation helpful? Give feedback.
-
That is correct, I was looking for a supertrait (I like the sound of it anyway and I'm pretty sure I've seen it in the Rust book) so that the compiler would error earlier when defining the problem versus when combining it with a solver. Thank you for highlighting the reasons why a supertrait would make the ergonomics worse. This is really what I am seeking, so hearing the larger context for its impact helps put the idea in perspective.
I agree, it is very clean and nice to only have to implement the traits for the particular solver, and setting up the problem definition is typically not fraught with type errors (like I have experienced using other solvers in the Rust ecosystem). This helps us get started quicker, but there could be some unforeseen type conflicts later on when we use a solver (I'll give my thoughts on how best to address this below).
That's a great idea! Thanks for sharing. This is nice for when you're setting up the problem, but for people doing the implementation of the problem they would still have to work with the ambiguous As I mentioned above, my objective with adding a supertrait would be to improve the ergonomics of the library. Based on your comment:
Could we define a supertrait for each solver that expresses what their bounds are and then include that in the problem definition? This could either be done by requiring a separate trait called These are just my musings, I'm not sure if this is even possible. I may take a look at implementing this to see if its even possible, but I've got other features that I want to work on that are needed for my application, so my time will be put into those first :) In the meantime, I think all of this is mitigated by having a section in the book that covers this topic. I can make an initial attempt at writing such a section if that sounds reasonable to you? Thank for the great discussion :) |
Beta Was this translation helpful? Give feedback.
-
That's a very good point.
We had that for one solver once and I recall not liking it, but I don't recall the reason anymore (probably just taste).
Apologies, I have trouble following this thought. Could you provide a code example, please? I think this would make it easier for me to understand. (Side note: there is already a
Contributions to the docs are always highly appreciated! :) I just had a look at the docs and admittedly, it is not easy to see the trait bounds. Pointing people to the right place would definitely help. |
Beta Was this translation helpful? Give feedback.
-
Ah, I can see that. With regards to putting together a code example, I will work on getting that once I nail down what exactly I mean :) I'll put together that PR for the docs soon. |
Beta Was this translation helpful? Give feedback.
-
Working with argmin has been a pleasure. I really appreciate the work that has gone into implementing these algorithms in Rust! Thank you for your hard work.
My question is concerning the use of argmin, where I don't understand how implementing a trait like
CostFunction
andGradient
using my own custom types for the associated types in those traits will result in a valid optimized problem. I am able to defineand this satisfies the
CostFunction
trait. That all seems reasonable. When I initialize myExecutor
the initial state is passed in with the correct parameter type and we can compute the cost based on that. However, when it comes to implementing theGradient
trait, and I use the same type for my input parameter, how doesargmin
know what the gradient means for these structs?If we are always working with numeric types (
f64
orf32
), I understand how the linear algebra of defining a Jacobian or some other matrix can work. You don't need to know what each parameter means, just that their values. This isn't true when using structs, like in my example. Could you please explain further how the algorithm handles these cases?I guess the other possibility is that
argmin
is not meant to handle arbitrary associated types in these traits, in which case I would have expected to have them restricted by the compiler. In my opinion, this is the correct way to go, or else everything has to be very generic!Beta Was this translation helpful? Give feedback.
All reactions