-
Notifications
You must be signed in to change notification settings - Fork 43
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
Questions about the C interface #148
Comments
I'm just seeing this.
|
The comment is exactly my question: why is it an issue if x0 is overwritten? Does this mean that we should check result.x instead of problem.x0 if we need x0 sometimes? I hope this is not the case in our code because the logic is wrong. Each variable/value should have one and only one meaning. result.x should never mean x0 and tell the user “I am sometimes the value of the returned x, but sometime x0; rely on me for x0 if you know what ‘sometimes’ means.” Logically, the result is not defined yet after the “initialisation” function is called. Therefore, each component should be set to a value indicating “I am not defined, so don’t use me”. To this end, we should set
Note that the logic is different from the initialisation of the options, even though they have some superficial similarities:
What do you think? |
I'm not sure what you propose? Should we remove
This I don't understand. All the algorithms take x as an argument and expect that it is initially equal to x0. They don't provide an input x0 and a separate output x parameter. It's the same with result.x in the current code.
This I also don't understand. I think I don't know what you mean by "defined" in this context. The result structure is defined in the header file. It is then initialized by I think it should be pointed out that |
@nbelakovski Reading your response, I believe that we are talking about completely different things ...
|
What I will do in
For me, this is the only reasonable "initialization" of Before the solver finishes its job, the result is not yet defined (mathematically or logically; not in the coding sense). Or in other words, the result does not exist. Its component should not be set to any particular values like x0 or 0. Why should some vector that is not yet defined (mathematically) take the value of x0? Why should some number that is not yet defined (mathematically) take the value 0? Then why not 1? What is particular about 0?
No. This sounds totally illogical to me. |
I think this is all very philosophical and if you'd like to change the initialization of result to what you've outlined, feel free to do so. I don't think it will make any difference. |
Sure, but this does not make it unimportant. Viewpoints are as important as implementations. Incorrect viewpoints will likely lead to wrong or improper implementations.
I will do it.
I agree, assuming that everything works and there is no bug hidden somewhere. However, it will reduce the potential of having bugs/confusion due to the initialization and make bugs much easier to spot if they occur. This has already happened in one of my tests --- no solver was invoked at all due to a mismatch of the problem of the solver, but Thank you. |
This sounds like This problem currently exists in Fortran as well for x/x0. Since x is set to x0 before calling a solver, it will seem to have a reasonable value even if the solver exit without a clean exit code.
I think there may be more consequential things to explore, such as setting up a profiler to take a look at the issue raised a couple weeks ago about the performance of PRIMA being substantially worse than another implementation of Powell's algorithms, even after expecting poorer performance due to the focus on code quality. Or working towards a unified interface in Fortran, or working on documentation. The focus on prima_init_result seems like it has less impact than some of those other items. |
This is not true. There is no solver selection in Fortran. There is no chance for the user to call a solver that does not match the problem. However, a similar problem does exist under some very marginal case for some other reasons, which I do not want to go in details here.
I agree that there are many things to do. The most urgent one is the Python binding and the integration to SciPy. (BTW, for your information, we are getting COBYQA into SciPy).
I do not think this is necessary. I have no plan for that. I am super reluctant to make any change to the Fortran code anymore.
Sure!
I suppose you meant #130. This is not really an issue. In short, we are not concerned about the CPU time in this kind of tests, where the function evaluations take no time. PRIMA is designed for black-box optimization problems where each function evaluation takes hours or days (this is the case for the real applications in Intel, Airbus, and Alibaba, for example). Thus we are only concerned about the number of function evaluations. I hope you can have a look at my response to the issue the explanations here: https://github.com/orgs/libprima/discussions/145
It takes a short time as long as I can confirm that what I proposed is not wrong. Again, I do not agree these kinds of changes are less important than those you listed. It avoids potential bugs and the importance is high. |
I made a comment in the relevant commits. You've introduced a possible memory leak and ignored x0 for all problems. So that's 2 bugs introduced and 0 fixed so far, if you don't mind I'll keep score until we close this issue :) It might be easier to do this in the form of a PR, instead of an an issue in which you make commits directly to main. |
Hi @nbelakovski , I have got two questions regarding the C interface.
problem->x0
intoresult->x
inprima/c/prima.c
Lines 120 to 121 in a617267
use_constr
inprima_minimize
and pass it toprima_check_problem
inprima/c/prima.c
Line 156 in a617267
Since
prima_check_problem
is the only place that usesuse_constr
, why don't we define it inprima_check_problem
?problem
andoptions
by pointers toprima_minimize
?prima/c/include/prima/prima.h
Line 241 in 19df480
In my opinion, they should be passed by value, as we do not intend to change them within the function --- if that is not our intention, then the possibility should be avoided as much as possible, to avoid accidental mistakes. Is there any disadvantage to pass by values here?
Thank you for taking a look.
The text was updated successfully, but these errors were encountered: