Re: [Math] LeastSquaresOptimizer Design

2015-09-25 Thread Ole Ersoy



On 09/25/2015 06:55 AM, Gilles wrote:

On Thu, 24 Sep 2015 21:41:10 -0500, Ole Ersoy wrote:

On 09/24/2015 06:01 PM, Gilles wrote:

On Thu, 24 Sep 2015 17:02:15 -0500, Ole Ersoy wrote:

On 09/24/2015 03:23 PM, Luc Maisonobe wrote:

Le 24/09/2015 21:40, Ole Ersoy a écrit :

Hi Luc,

I gave this some more thought, and I think I may have tapped out to
soon, even though you are absolutely right about what an exception does
in terms bubbling execution to a point where it stops or we handle it.

Suppose we have an Optimizer and an Optimizer observer. The optimizer
will emit three different events given in the process of stepping
through to the max number of iterations it is allotted:
- SOLUTION_FOUND
- COULD_NOT_CONVERGE_FOR_REASON_1
- COULD_NOT_CONVERGE_FOR_REASON_2
- END (Max iterations reached)

So we have the observer interface:

interface OptimizerObserver {

 success(Solution solution)
 update(Enum enum, Optimizer optimizer)
 end(Optimizer optimizer)
}

So if the Optimizer notifies the observer of `success`, then the
observer does what it needs to with the results and moves on.  If the
observer gets an `update` notification, that means that given the
current [constraints, numbers of iterations, data] the optimizer cannot
finish.  But the update method receives the optimizer, so it can adapt
it, and tell it to continue or just trash it and try something
completely different.  If the `END` event is reached then the Optimizer
could not finish given the number of allotted iterations. The Optimizer
is passed back via the callback interface so the observer could allow
more iterations if it wants to...perhaps based on some metric indicating
how close the optimizer is to finding a solution.

What this could do is allow the implementation of the observer to throw
the exception if 'All is lost!', in which case the Optimizer does not
need an exception.  Totally understand that this may not work
everywhere, but it seems like it could work in this case.

WDYT?

With this version, you should also pass the optimizer in case of
success. In most cases, the observer will just ignore it, but in some
cases it may try to solve another problem, or to solve again with
stricter constraints, using the previous solution as the start point
for the more stringent problem. Another case would be to go from a
simple problem to a more difficult problem using some kind of
homotopy.

Great - whoooh - glad you like this version a little better - for a
sec I thought I had complete lost it :).


IIUC, I don't like it: it looks like "GOTO"...


Inside the optimizer it would work like this:

while (!done) {
   if (can't converge) {
   observer.update(Enum.CANT_CONVERGE, this);
   }
}


That's fine. What I don't like is to have provision for changing the
optimizer's settings and reuse the same instance.

If the design of the optimizer allows for this, then the interface for the 
Observer would facilitate it.  The person implementing the interface could 
throw an exception when they get the Enum.CANT_CONVERGE message, in which case 
the semantics are the same as they are now.

On the other hand if the optimizer is not designed for reuse, perhaps for the 
reason that it causes more complexity than it's worth, the Observer interface 
could just exclude this aspect.


The optimizer should be instantiated at the lowest possible level; it
will report everything to the observer, but the "report" is not to be
confused with the "optimizer".

The design of the observer is flexible.  It gives the person implementing the 
interface the ability to change the state of what is being observed.  It's a 
bit like warming up leftovers.  You are the observer.  You grab yesterdays the 
pizza.  Throw in in the microwave.  The microwave is the optimizer.  We hit the 
30 second button, and check on the pizza.  If we like it, we take it out, 
otherwise we hit 30 seconds again, or we throw the whole thing out, because we 
just realized that the Pizza rat took a chunk out:
https://www.youtube.com/watch?v=UPXUG8q4jKU





Then in the update method either modify the optimizer's parameters or
throw an exception.


If I'm referring to Luc's example of a high-level code "H" call to some
mid-level code "M" itself calling CM's optimizer "CM", then "M" may not
have enough info to know whether it's OK to retry "CM", but on the other
hand, "H" might not even be aware that "M" is using "CM".

So in this case the person implementing the Observer interface would keep the 
semantics that we have now.  There is one important distinction though.  The 
person uses the Enum parameter, indicating the root cause of the message, to 
throw their own (Meaningful to them) exception.



As I tried to explain several times along the years (but failed to
convince) is that the same problem exists with the exceptions: however
detailed the message, it might not make sense to the person that reads
the console because he is at level "H" and may have no idea that "CM"
is used deep 

Re: [Math] LeastSquaresOptimizer Design

2015-09-25 Thread Gilles

On Thu, 24 Sep 2015 21:41:10 -0500, Ole Ersoy wrote:

On 09/24/2015 06:01 PM, Gilles wrote:

On Thu, 24 Sep 2015 17:02:15 -0500, Ole Ersoy wrote:

On 09/24/2015 03:23 PM, Luc Maisonobe wrote:

Le 24/09/2015 21:40, Ole Ersoy a écrit :

Hi Luc,

I gave this some more thought, and I think I may have tapped out 
to
soon, even though you are absolutely right about what an 
exception does
in terms bubbling execution to a point where it stops or we 
handle it.


Suppose we have an Optimizer and an Optimizer observer.  The 
optimizer

will emit three different events given in the process of stepping
through to the max number of iterations it is allotted:
- SOLUTION_FOUND
- COULD_NOT_CONVERGE_FOR_REASON_1
- COULD_NOT_CONVERGE_FOR_REASON_2
- END (Max iterations reached)

So we have the observer interface:

interface OptimizerObserver {

 success(Solution solution)
 update(Enum enum, Optimizer optimizer)
 end(Optimizer optimizer)
}

So if the Optimizer notifies the observer of `success`, then the
observer does what it needs to with the results and moves on.  If 
the

observer gets an `update` notification, that means that given the
current [constraints, numbers of iterations, data] the optimizer 
cannot
finish.  But the update method receives the optimizer, so it can 
adapt

it, and tell it to continue or just trash it and try something
completely different.  If the `END` event is reached then the 
Optimizer
could not finish given the number of allotted iterations. The 
Optimizer
is passed back via the callback interface so the observer could 
allow
more iterations if it wants to...perhaps based on some metric 
indicating

how close the optimizer is to finding a solution.

What this could do is allow the implementation of the observer to 
throw
the exception if 'All is lost!', in which case the Optimizer does 
not

need an exception.  Totally understand that this may not work
everywhere, but it seems like it could work in this case.

WDYT?

With this version, you should also pass the optimizer in case of
success. In most cases, the observer will just ignore it, but in 
some

cases it may try to solve another problem, or to solve again with
stricter constraints, using the previous solution as the start 
point

for the more stringent problem. Another case would be to go from a
simple problem to a more difficult problem using some kind of
homotopy.

Great - whoooh - glad you like this version a little better - for a
sec I thought I had complete lost it :).


IIUC, I don't like it: it looks like "GOTO"...


Inside the optimizer it would work like this:

while (!done) {
   if (can't converge) {
   observer.update(Enum.CANT_CONVERGE, this);
   }
}


That's fine. What I don't like is to have provision for changing the
optimizer's settings and reuse the same instance.
The optimizer should be instantiated at the lowest possible level; it
will report everything to the observer, but the "report" is not to be
confused with the "optimizer".



Then in the update method either modify the optimizer's parameters or
throw an exception.


If I'm referring to Luc's example of a high-level code "H" call to some
mid-level code "M" itself calling CM's optimizer "CM", then "M" may not
have enough info to know whether it's OK to retry "CM", but on the 
other

hand, "H" might not even be aware that "M" is using "CM".

As I tried to explain several times along the years (but failed to
convince) is that the same problem exists with the exceptions: however
detailed the message, it might not make sense to the person that reads
the console because he is at level "H" and may have no idea that "CM"
is used deep down.
Having a specific exception which "M" can catch, extract info from, and
raise a more meaningful exception (and/or translate the message!) is a
much more flexible solution IMO.


Note to seeelf ... cancel
therapy with Dr. Phil.  BTW - Gilles - this could also be used as a
light weight logger.


I don't like this either (reinventing the wheel).


You still want me to go and see Dr. Phil? :)


I just wish that we are allowed to use slf4j directly within CM.
Is there any reason to go through hoops in order to offer this facility
to users and developers?

[Well, if all iterative algorithms are rewritten within the "observer"
paradigm, then the logging can indeed be left at the caller's level 
(since
the optimizer will report "everything"...  Going that route is an 
option

to be mentioned in issue of allowing "slf4j" or not (see below).]


The Optimizer could publish information deemed
interesting on each ITERATION event.


If we'd go for an "OptimizerObserver" that gets called at every
iteration,
there shouldn't be any overlap between it and "Optimizer":

So inside the Optimizer we could have:

while (!done) {
...
if (observer.notifyOnIncrement())
{
observer.increment(this);
}
}

Which would give us an opportunity to cancel the run if, for example,
it's not converging fast enough.


Providing ways 

Re: [Math] LeastSquaresOptimizer Design

2015-09-25 Thread Gilles

On Thu, 24 Sep 2015 22:07:58 -0500, Ole Ersoy wrote:

Why should the instance throwing the exception hold a field with the
information?
Separation of concerns: optimizer does the computation,
then the exception holds what's needed for a full report of the 
failure.

I would see what makes sense on on case by case basis.  For example
if the Observer, which is implemented by the client / person using 
CM,

realizes that it can't continue it can throw an application specific
exception using a set of Enums that are coded for the application.

if ( optimizer.yourNeverGonnaGetItEver() ) {

   throw new
ApplicationSpecificException(ApplicationErrorCodes.PARTYS_OVER,
optimizer);
}

The error code should be specific enough for the application to
understand the the optimizer argument is the optimizer (Object type),
and then it can construct the message from there.


IMO, we shouldn't force the optimizer instance to hold fields just for
the sake of reporting (the optimizer could make a "CurrentStateReport"
instances on the fly to be passed to the observer at every iteration).

Unless I'm missing something, I don't see the benefit of passing the
optimizer.
All arguments used to instantiate the optimizer must be known already
at the caller's level.  The "CurrentStateReport" should only contain
computed values that would allow the caller to decide whether to stop
or continue. In the former case, the caller would be responsible to
merge the initial arguments list and computed values in order to
proceed (e.g. instantiate a new optimizer with the current best model
parameters as initial values).



Or the report is done at the observer's level, based on complete
information routinely returned by the optimizer at every step (cf.
previous mail).

I would stick with the same process in this case.


?

Regards,
Gilles



Cheers,
- Ole



-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org



Re: [Math] LeastSquaresOptimizer Design

2015-09-24 Thread luc

Le 2015-09-24 04:16, Ole Ersoy a écrit :

On 09/23/2015 03:09 PM, Luc Maisonobe wrote:
CM is not intended to be a design pattern people should mimic. We are 
so bad at this it would be a shame. No one in its right mind would 
copy or reuse this stuff. It is for internal use only and we don't 
even have the resources to manage it by ourselves so we can't consider 
it as a path people should follow as we are leading them. Here we 
would be leading them directly against the wall.


Hehe - I think that's like Michael Jordan saying - "Guys, don't try to
be like me.  I just play a little ball.  Dunk from the free throw
line.  Six world championships, but THATs it!".  In any case, I really
appreciate you and Gilles taking the time to talk.  Luc (And possibly
Gilles) - I can actually see why you are getting a bit annoyed,
because I'm ignoring something important.

I've been doing 90% NodeJS stuff lately (Which is event loop based and
relies callbacks) so I forgot one very important thing that I think
you have both tried to tell me.  The exception undoes the current
callstack / breaks the current program flow, bubbling up to the
handler.  Thts a good point.

OK - So scratch the callback thinking for synchronous code.  The
Lombok stuff should still be good though and hopefully some of the
callback discussion around and asynchronous option - I hope!  Geez.

What do you think about having one exception per class with an Enum
that encodes the various types of exceptional conditions that the
class can find itself in?  So in the case of
LevenbergMarquardtOptimizer there would be a:
- LevenbergMarquardtOptimizerException:
- LevenbergMarquardtOptimizerExceptionEnum

When the exception is thrown it sets the Enum indicating the root
cause.  The enum can then be used as a key to lookup the corresponding
message.

Any better?


Sure. I would suggest adding some parameters to help the upper level 
formatting
a meaningful message (say the number of iterations performed if you hit 
a max
iteration, so users become aware they should have set the limit higher). 
Nothing
over-engineered, a simple Object[] that can be used as last argument to 
something

like String.format() would be enough.

best regards,
Luc



Cheers,
- Ole


-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org


-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org



Re: [Math] LeastSquaresOptimizer Design

2015-09-24 Thread luc

Hi Gilles,

Le 2015-09-23 23:00, Gilles a écrit :

[...]

CM is not intended to be a design pattern people should mimic.
We are so bad at this


The crux is that the project's team is in effect not _interested_
in this.  [And I admit that I had not understood it for a long
time (hence the temptation to convince that it was important for
*some* people).]


it would be a shame. No one in its right mind would copy
or reuse this stuff. It is for internal use only


Then why is it so difficult to change (cf. all the nit-picking
about backward-compatibility)?
As was (relatively) recently discussed, we could "mark" some code
"for internal use" and be free to break compatibility at any time,
for the sake of (an attempt at) a better design.


I think it would be nice. IMHO, we are overzealous on compatibility.
Sometimes, I try to introduce some changes that may break compatibility
early for some non user-implementable interfaces but have to withdraw
my proposal (tried it for ode, tried ot for BSP trees, think I tried it
for optimizers).




and we don't even have
the resources to manage it by ourselves


There are (maybe) other people (like Ole?) who would like to
experiment with new design ideas (not new math algorithms!)
but are repelled by the (overly) conservative development process
which is mainly feature-driven (like in a commercial project,
shall I dare to say).


Surely. But it is not specifically commercial vs open source I think.
I know commercial projects that break compatibility all the time 
(perhaps

to force users buying a new licence) and some that are stable. I know
open-source projects that break compatibility all the time (perhaps
because the team is highly dynamic or doesn't care about users) and
some that are stable.




so we can't consider it as a
path people should follow as we are leading them. Here we would be
leading them directly against the wall.


True, unfortunately.
There is really no long-term design. Even short term (quasi-)decisions
when they concern the library as a whole, are not followed by action
(cf. "fluent API")...


I still have fluent API in my TODO list and still really wants to make
it appear. The major blocking factor is available time (and sometimes
also despair about probable endless forthcoming discussions but it is
only second in the list).

best regards,
Luc




[...]


Best,
Gilles


-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org


-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org



Re: [Math] LeastSquaresOptimizer Design

2015-09-24 Thread Ole Ersoy



On 09/24/2015 06:31 AM, luc wrote:

Le 2015-09-24 04:16, Ole Ersoy a écrit :

On 09/23/2015 03:09 PM, Luc Maisonobe wrote:

CM is not intended to be a design pattern people should mimic. We are so bad at 
this it would be a shame. No one in its right mind would copy or reuse this 
stuff. It is for internal use only and we don't even have the resources to 
manage it by ourselves so we can't consider it as a path people should follow 
as we are leading them. Here we would be leading them directly against the wall.


Hehe - I think that's like Michael Jordan saying - "Guys, don't try to
be like me.  I just play a little ball.  Dunk from the free throw
line.  Six world championships, but THATs it!".  In any case, I really
appreciate you and Gilles taking the time to talk.  Luc (And possibly
Gilles) - I can actually see why you are getting a bit annoyed,
because I'm ignoring something important.

I've been doing 90% NodeJS stuff lately (Which is event loop based and
relies callbacks) so I forgot one very important thing that I think
you have both tried to tell me.  The exception undoes the current
callstack / breaks the current program flow, bubbling up to the
handler.  Thts a good point.

OK - So scratch the callback thinking for synchronous code.  The
Lombok stuff should still be good though and hopefully some of the
callback discussion around and asynchronous option - I hope! Geez.

What do you think about having one exception per class with an Enum
that encodes the various types of exceptional conditions that the
class can find itself in?  So in the case of
LevenbergMarquardtOptimizer there would be a:
- LevenbergMarquardtOptimizerException:
- LevenbergMarquardtOptimizerExceptionEnum

When the exception is thrown it sets the Enum indicating the root
cause.  The enum can then be used as a key to lookup the corresponding
message.

Any better?


Sure. I would suggest adding some parameters to help the upper level formatting
a meaningful message (say the number of iterations performed if you hit a max
iteration, so users become aware they should have set the limit higher). Nothing
over-engineered, a simple Object[] that can be used as last argument to 
something
like String.format() would be enough.

Brilliant - I'll setup a repository and start experimenting.  Thanks again,
- Ole


-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org



Re: [Math] LeastSquaresOptimizer Design

2015-09-24 Thread Ole Ersoy

Hi Luc,

I gave this some more thought, and I think I may have tapped out to soon, even 
though you are absolutely right about what an exception does in terms bubbling 
execution to a point where it stops or we handle it.

Suppose we have an Optimizer and an Optimizer observer.  The optimizer will 
emit three different events given in the process of stepping through to the max 
number of iterations it is allotted:
- SOLUTION_FOUND
- COULD_NOT_CONVERGE_FOR_REASON_1
- COULD_NOT_CONVERGE_FOR_REASON_2
- END (Max iterations reached)

So we have the observer interface:

interface OptimizerObserver {

success(Solution solution)
update(Enum enum, Optimizer optimizer)
end(Optimizer optimizer)
}

So if the Optimizer notifies the observer of `success`, then the observer does 
what it needs to with the results and moves on.  If the observer gets an 
`update` notification, that means that given the current [constraints, numbers 
of iterations, data] the optimizer cannot finish.  But the update method 
receives the optimizer, so it can adapt it, and tell it to continue or just 
trash it and try something completely different.  If the `END` event is reached 
then the Optimizer could not finish given the number of allotted iterations.  
The Optimizer is passed back via the callback interface so the observer could 
allow more iterations if it wants to...perhaps based on some metric indicating 
how close the optimizer is to finding a solution.

What this could do is allow the implementation of the observer to throw the 
exception if 'All is lost!', in which case the Optimizer does not need an 
exception.  Totally understand that this may not work everywhere, but it seems 
like it could work in this case.

WDYT?

Cheers,
- Ole



On 09/23/2015 03:09 PM, Luc Maisonobe wrote:

Le 23/09/2015 19:20, Ole Ersoy a écrit :

HI Luc,

Hi Ole,


On 09/23/2015 03:02 AM, luc wrote:

Hi,

Le 2015-09-22 02:55, Ole Ersoy a écrit :

Hola,

On 09/21/2015 04:15 PM, Gilles wrote:

Hi.

On Sun, 20 Sep 2015 15:04:08 -0500, Ole Ersoy wrote:

On 09/20/2015 05:51 AM, Gilles wrote:

On Sun, 20 Sep 2015 01:12:49 -0500, Ole Ersoy wrote:

Wanted to float some ideas for the LeastSquaresOptimizer (Possibly
General Optimizer) design.  For example with the
LevenbergMarquardtOptimizer we would do:
`LevenbergMarquardtOptimizer.optimize(OptimizationContext c);`

Rough optimize() outline:
public static void optimise() {
//perform the optimization
//If successful
 c.notify(LevenberMarquardtResultsEnum.SUCCESS, solution);
//If not successful


c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_COST_RELATIVE_TOLERANCE,

diagnostic);
//or


c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_PARAMETERS_RELATIVE_TOLERANCE,

diagnostic)
//etc
}

The diagnostic, when turned on, will contain a trace of the last N
iterations leading up to the failure.  When turned off, the
Diagnostic
instance only contains the parameters used to detect failure. The
diagnostic could be viewed as an indirect way to log optimizer
iterations.

WDYT?

I'm wary of having several different ways to convey information to
the
caller.

It would just be one way.

One way for optimizer, one way for solvers, one way for ...

Yes I see what you mean, but I think on a whole it will be worth it to
add additional sugar code that removes the need for exceptions.


But the caller may not be the receiver
(It could be).  The receiver would be an observer attached to the
OptimizationContext that implements an interface allowing it to
observe
the optimization.

I'm afraid that it will add to the questions of what to put in the
code and how.  [We already had sometimes heated discussions just for
the IMHO obvious (e.g. code formatting, documentation, exception...).]

Hehe.  Yes I remember some of these discussions.  I wonder how much
time was spent debating the exceptions alone?  Surely everyone must
have had this feeling in pit of their stomach that there's got to be a
better way.  On the exception topic, these are some of the issues:

I18N
===
If you are new to commons math and thinking about designing a commons
math compatible exception you should probably understand the I18N
stuff that's bound to exception (and wonder why it's bound the the
exception).

Not really true.

Well a lot of things are gray.  Personally if I'm dealing with an API, I
like to understand it, so that there are no surprises.  And I understand
that the I18N coupling might not force me to use it, but if I want to be
smart about my architecture, and simplify my design, then I should look
at it.  Maybe it is a good idea.  Maybe I should just gloss over it?  Am
I being sloppy if I just gloss over it?

Or is there an alternative that provides the same functionality, or
maybe something better, that does not come with any of these side effects?


The I18N was really simple at start.

Yup I reviewed it and thought - it's probably no big deal - but as I
started looking into reusing the CM exceptions, I decided that it 

Re: [Math] LeastSquaresOptimizer Design

2015-09-24 Thread Gilles

On Thu, 24 Sep 2015 08:43:38 -0500, Ole Ersoy wrote:

On 09/24/2015 06:31 AM, luc wrote:

Le 2015-09-24 04:16, Ole Ersoy a écrit :

On 09/23/2015 03:09 PM, Luc Maisonobe wrote:
CM is not intended to be a design pattern people should mimic. We 
are so bad at this it would be a shame. No one in its right mind 
would copy or reuse this stuff. It is for internal use only and we 
don't even have the resources to manage it by ourselves so we can't 
consider it as a path people should follow as we are leading them. 
Here we would be leading them directly against the wall.


Hehe - I think that's like Michael Jordan saying - "Guys, don't try 
to

be like me.  I just play a little ball.  Dunk from the free throw
line.  Six world championships, but THATs it!".  In any case, I 
really
appreciate you and Gilles taking the time to talk.  Luc (And 
possibly

Gilles) - I can actually see why you are getting a bit annoyed,
because I'm ignoring something important.

I've been doing 90% NodeJS stuff lately (Which is event loop based 
and

relies callbacks) so I forgot one very important thing that I think
you have both tried to tell me.  The exception undoes the current
callstack / breaks the current program flow, bubbling up to the
handler.  Thts a good point.

OK - So scratch the callback thinking for synchronous code.  The
Lombok stuff should still be good though and hopefully some of the
callback discussion around and asynchronous option - I hope! Geez.

What do you think about having one exception per class with an Enum
that encodes the various types of exceptional conditions that the
class can find itself in?  So in the case of
LevenbergMarquardtOptimizer there would be a:
- LevenbergMarquardtOptimizerException:
- LevenbergMarquardtOptimizerExceptionEnum

When the exception is thrown it sets the Enum indicating the root
cause.  The enum can then be used as a key to lookup the 
corresponding

message.

Any better?


Sure. I would suggest adding some parameters to help the upper level 
formatting
a meaningful message (say the number of iterations performed if you 
hit a max
iteration, so users become aware they should have set the limit 
higher). Nothing
over-engineered, a simple Object[] that can be used as last argument 
to something

like String.format() would be enough.
Brilliant - I'll setup a repository and start experimenting.  Thanks 
again,

- Ole


I don't understand what Luc proposed.
But just having "Object[]" mentioned makes me shiver... :-{

Thanks to the "ExceptionContext" it is readily possible to add as many 
"messages"
as we want to be displayed. [There is no need to ask the caller to use 
"format()"

as it is done in CM.]
And there are also a methods for setting and getting an "Object".

I'd be for using more (possibly "local") exceptions if we want to 
convey
more, and more specific, information.  This should be done with getters 
that

return typed information, not "Object"s.

Gilles


-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org



Re: [Math] LeastSquaresOptimizer Design

2015-09-24 Thread Ole Ersoy



On 09/24/2015 03:23 PM, Luc Maisonobe wrote:

Le 24/09/2015 21:40, Ole Ersoy a écrit :

Hi Luc,

I gave this some more thought, and I think I may have tapped out to
soon, even though you are absolutely right about what an exception does
in terms bubbling execution to a point where it stops or we handle it.

Suppose we have an Optimizer and an Optimizer observer.  The optimizer
will emit three different events given in the process of stepping
through to the max number of iterations it is allotted:
- SOLUTION_FOUND
- COULD_NOT_CONVERGE_FOR_REASON_1
- COULD_NOT_CONVERGE_FOR_REASON_2
- END (Max iterations reached)

So we have the observer interface:

interface OptimizerObserver {

 success(Solution solution)
 update(Enum enum, Optimizer optimizer)
 end(Optimizer optimizer)
}

So if the Optimizer notifies the observer of `success`, then the
observer does what it needs to with the results and moves on.  If the
observer gets an `update` notification, that means that given the
current [constraints, numbers of iterations, data] the optimizer cannot
finish.  But the update method receives the optimizer, so it can adapt
it, and tell it to continue or just trash it and try something
completely different.  If the `END` event is reached then the Optimizer
could not finish given the number of allotted iterations.  The Optimizer
is passed back via the callback interface so the observer could allow
more iterations if it wants to...perhaps based on some metric indicating
how close the optimizer is to finding a solution.

What this could do is allow the implementation of the observer to throw
the exception if 'All is lost!', in which case the Optimizer does not
need an exception.  Totally understand that this may not work
everywhere, but it seems like it could work in this case.

WDYT?

With this version, you should also pass the optimizer in case of
success. In most cases, the observer will just ignore it, but in some
cases it may try to solve another problem, or to solve again with
stricter constraints, using the previous solution as the start point
for the more stringent problem. Another case would be to go from a
simple problem to a more difficult problem using some kind of
homotopy.

Great - whoooh - glad you like this version a little better - for a sec I 
thought I had complete lost it :).  Note to seeelf ... cancel therapy with Dr. 
Phil.  BTW - Gilles - this could also be used as a light weight logger.  The 
Optimizer could publish information deemed interesting on each ITERATION event. 
 The observer could then be wired with SLF4J and perform the same type of 
logging that the Optimizer would perform.  So CM could declare SLF4J as a test 
dependency, and unit tests could log iterations using it.

Lombok also has a @SLF4J annotation that's pretty sweet.  Saves the SLF4J 
boilerplate.

Cheers,
- Ole



best regards,
Luc


Cheers,
- Ole



On 09/23/2015 03:09 PM, Luc Maisonobe wrote:

Le 23/09/2015 19:20, Ole Ersoy a écrit :

HI Luc,

Hi Ole,


On 09/23/2015 03:02 AM, luc wrote:

Hi,

Le 2015-09-22 02:55, Ole Ersoy a écrit :

Hola,

On 09/21/2015 04:15 PM, Gilles wrote:

Hi.

On Sun, 20 Sep 2015 15:04:08 -0500, Ole Ersoy wrote:

On 09/20/2015 05:51 AM, Gilles wrote:

On Sun, 20 Sep 2015 01:12:49 -0500, Ole Ersoy wrote:

Wanted to float some ideas for the LeastSquaresOptimizer (Possibly
General Optimizer) design.  For example with the
LevenbergMarquardtOptimizer we would do:
`LevenbergMarquardtOptimizer.optimize(OptimizationContext c);`

Rough optimize() outline:
public static void optimise() {
//perform the optimization
//If successful
  c.notify(LevenberMarquardtResultsEnum.SUCCESS, solution);
//If not successful


c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_COST_RELATIVE_TOLERANCE,


diagnostic);
//or


c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_PARAMETERS_RELATIVE_TOLERANCE,


diagnostic)
//etc
}

The diagnostic, when turned on, will contain a trace of the last N
iterations leading up to the failure.  When turned off, the
Diagnostic
instance only contains the parameters used to detect failure. The
diagnostic could be viewed as an indirect way to log optimizer
iterations.

WDYT?

I'm wary of having several different ways to convey information to
the
caller.

It would just be one way.

One way for optimizer, one way for solvers, one way for ...

Yes I see what you mean, but I think on a whole it will be worth it to
add additional sugar code that removes the need for exceptions.


But the caller may not be the receiver
(It could be).  The receiver would be an observer attached to the
OptimizationContext that implements an interface allowing it to
observe
the optimization.

I'm afraid that it will add to the questions of what to put in the
code and how.  [We already had sometimes heated discussions just for
the IMHO obvious (e.g. code formatting, documentation,
exception...).]

Hehe.  Yes I remember some of these discussions.  I wonder how much
time was spent debating the exceptions alone?  

Re: [Math] LeastSquaresOptimizer Design

2015-09-24 Thread Ole Ersoy



On 09/24/2015 04:05 PM, Gilles wrote:

On Thu, 24 Sep 2015 08:43:38 -0500, Ole Ersoy wrote:

On 09/24/2015 06:31 AM, luc wrote:

Le 2015-09-24 04:16, Ole Ersoy a écrit :

On 09/23/2015 03:09 PM, Luc Maisonobe wrote:

CM is not intended to be a design pattern people should mimic. We are so bad at 
this it would be a shame. No one in its right mind would copy or reuse this 
stuff. It is for internal use only and we don't even have the resources to 
manage it by ourselves so we can't consider it as a path people should follow 
as we are leading them. Here we would be leading them directly against the wall.


Hehe - I think that's like Michael Jordan saying - "Guys, don't try to
be like me.  I just play a little ball.  Dunk from the free throw
line.  Six world championships, but THATs it!".  In any case, I really
appreciate you and Gilles taking the time to talk.  Luc (And possibly
Gilles) - I can actually see why you are getting a bit annoyed,
because I'm ignoring something important.

I've been doing 90% NodeJS stuff lately (Which is event loop based and
relies callbacks) so I forgot one very important thing that I think
you have both tried to tell me.  The exception undoes the current
callstack / breaks the current program flow, bubbling up to the
handler.  Thts a good point.

OK - So scratch the callback thinking for synchronous code. The
Lombok stuff should still be good though and hopefully some of the
callback discussion around and asynchronous option - I hope! Geez.

What do you think about having one exception per class with an Enum
that encodes the various types of exceptional conditions that the
class can find itself in?  So in the case of
LevenbergMarquardtOptimizer there would be a:
- LevenbergMarquardtOptimizerException:
- LevenbergMarquardtOptimizerExceptionEnum

When the exception is thrown it sets the Enum indicating the root
cause.  The enum can then be used as a key to lookup the corresponding
message.

Any better?


Sure. I would suggest adding some parameters to help the upper level formatting
a meaningful message (say the number of iterations performed if you hit a max
iteration, so users become aware they should have set the limit higher). Nothing
over-engineered, a simple Object[] that can be used as last argument to 
something
like String.format() would be enough.

Brilliant - I'll setup a repository and start experimenting. Thanks again,
- Ole


I don't understand what Luc proposed.
But just having "Object[]" mentioned makes me shiver... :-{

Thanks to the "ExceptionContext" it is readily possible to add as many 
"messages"
as we want to be displayed. [There is no need to ask the caller to use 
"format()"
as it is done in CM.]
And there are also a methods for setting and getting an "Object".

I'd be for using more (possibly "local") exceptions if we want to convey
more, and more specific, information.  This should be done with getters that
return typed information, not "Object"s.


Javascripters do what Luc is advocating all the time, so I'm used to it.

If the exception is specific to the class throwing the exception then we could 
attach a reference to the instance throwing the exception and use Lombok to 
generate binary getters.

Cheers,
- Ole



Gilles


-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org





-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org



Re: [Math] LeastSquaresOptimizer Design

2015-09-24 Thread Gilles

On Thu, 24 Sep 2015 17:02:15 -0500, Ole Ersoy wrote:

On 09/24/2015 03:23 PM, Luc Maisonobe wrote:

Le 24/09/2015 21:40, Ole Ersoy a écrit :

Hi Luc,

I gave this some more thought, and I think I may have tapped out to
soon, even though you are absolutely right about what an exception 
does
in terms bubbling execution to a point where it stops or we handle 
it.


Suppose we have an Optimizer and an Optimizer observer.  The 
optimizer

will emit three different events given in the process of stepping
through to the max number of iterations it is allotted:
- SOLUTION_FOUND
- COULD_NOT_CONVERGE_FOR_REASON_1
- COULD_NOT_CONVERGE_FOR_REASON_2
- END (Max iterations reached)

So we have the observer interface:

interface OptimizerObserver {

 success(Solution solution)
 update(Enum enum, Optimizer optimizer)
 end(Optimizer optimizer)
}

So if the Optimizer notifies the observer of `success`, then the
observer does what it needs to with the results and moves on.  If 
the

observer gets an `update` notification, that means that given the
current [constraints, numbers of iterations, data] the optimizer 
cannot
finish.  But the update method receives the optimizer, so it can 
adapt

it, and tell it to continue or just trash it and try something
completely different.  If the `END` event is reached then the 
Optimizer
could not finish given the number of allotted iterations.  The 
Optimizer
is passed back via the callback interface so the observer could 
allow
more iterations if it wants to...perhaps based on some metric 
indicating

how close the optimizer is to finding a solution.

What this could do is allow the implementation of the observer to 
throw
the exception if 'All is lost!', in which case the Optimizer does 
not

need an exception.  Totally understand that this may not work
everywhere, but it seems like it could work in this case.

WDYT?

With this version, you should also pass the optimizer in case of
success. In most cases, the observer will just ignore it, but in 
some

cases it may try to solve another problem, or to solve again with
stricter constraints, using the previous solution as the start point
for the more stringent problem. Another case would be to go from a
simple problem to a more difficult problem using some kind of
homotopy.

Great - whoooh - glad you like this version a little better - for a
sec I thought I had complete lost it :).


IIUC, I don't like it: it looks like "GOTO"...


Note to seeelf ... cancel
therapy with Dr. Phil.  BTW - Gilles - this could also be used as a
light weight logger.


I don't like this either (reinventing the wheel).


The Optimizer could publish information deemed
interesting on each ITERATION event.


If we'd go for an "OptimizerObserver" that gets called at every
iteration, there shouldn't be any overlap between it and "Optimizer":
iteration limit should be dealt with by the observer, the iterative
algorithm would just run "forever" until the observer is satisfied
with the current state (solution is good enough or the allotted
resources - be they time, iterations, evaluations, ... - are
exhausted).


The observer could then be wired
with SLF4J and perform the same type of logging that the Optimizer
would perform.  So CM could declare SLF4J as a test dependency, and
unit tests could log iterations using it.


As a "user", I'm interested in how the algorithms behave on my problem,
not in the CM unit tests.

The question remains unanswered: why not use slf4j directly?


Lombok also has a @SLF4J annotation that's pretty sweet.  Saves the
SLF4J boilerplate.


I understand that using annotations can be a time-saver, but IMO not
so much for a library like CM; so in this case, the risk of depending
on another library must be weighed against the advantages.

Regards,
Gilles


Cheers,
- Ole


[...]



-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org



Re: [Math] LeastSquaresOptimizer Design

2015-09-24 Thread Gilles

On Thu, 24 Sep 2015 18:01:13 -0500, Ole Ersoy wrote:

On 09/24/2015 04:05 PM, Gilles wrote:

On Thu, 24 Sep 2015 08:43:38 -0500, Ole Ersoy wrote:

On 09/24/2015 06:31 AM, luc wrote:

Le 2015-09-24 04:16, Ole Ersoy a écrit :

On 09/23/2015 03:09 PM, Luc Maisonobe wrote:
CM is not intended to be a design pattern people should mimic. 
We are so bad at this it would be a shame. No one in its right 
mind would copy or reuse this stuff. It is for internal use only 
and we don't even have the resources to manage it by ourselves so 
we can't consider it as a path people should follow as we are 
leading them. Here we would be leading them directly against the 
wall.


Hehe - I think that's like Michael Jordan saying - "Guys, don't 
try to

be like me.  I just play a little ball.  Dunk from the free throw
line.  Six world championships, but THATs it!".  In any case, I 
really
appreciate you and Gilles taking the time to talk.  Luc (And 
possibly

Gilles) - I can actually see why you are getting a bit annoyed,
because I'm ignoring something important.

I've been doing 90% NodeJS stuff lately (Which is event loop 
based and
relies callbacks) so I forgot one very important thing that I 
think

you have both tried to tell me.  The exception undoes the current
callstack / breaks the current program flow, bubbling up to the
handler.  Thts a good point.

OK - So scratch the callback thinking for synchronous code. The
Lombok stuff should still be good though and hopefully some of 
the
callback discussion around and asynchronous option - I hope! 
Geez.


What do you think about having one exception per class with an 
Enum

that encodes the various types of exceptional conditions that the
class can find itself in?  So in the case of
LevenbergMarquardtOptimizer there would be a:
- LevenbergMarquardtOptimizerException:
- LevenbergMarquardtOptimizerExceptionEnum

When the exception is thrown it sets the Enum indicating the root
cause.  The enum can then be used as a key to lookup the 
corresponding

message.

Any better?


Sure. I would suggest adding some parameters to help the upper 
level formatting
a meaningful message (say the number of iterations performed if 
you hit a max
iteration, so users become aware they should have set the limit 
higher). Nothing
over-engineered, a simple Object[] that can be used as last 
argument to something

like String.format() would be enough.
Brilliant - I'll setup a repository and start experimenting. Thanks 
again,

- Ole


I don't understand what Luc proposed.
But just having "Object[]" mentioned makes me shiver... :-{

Thanks to the "ExceptionContext" it is readily possible to add as 
many "messages"
as we want to be displayed. [There is no need to ask the caller to 
use "format()"

as it is done in CM.]
And there are also a methods for setting and getting an "Object".

I'd be for using more (possibly "local") exceptions if we want to 
convey
more, and more specific, information.  This should be done with 
getters that

return typed information, not "Object"s.


Javascripters do what Luc is advocating all the time, so I'm used to 
it.


If the exception is specific to the class throwing the exception then
we could attach a reference to the instance throwing the exception 
and

use Lombok to generate binary getters.



Why should the instance throwing the exception hold a field with the
information? Separation of concerns: optimizer does the computation,
then the exception holds what's needed for a full report of the 
failure.


Or the report is done at the observer's level, based on complete
information routinely returned by the optimizer at every step (cf.
previous mail).

Gilles


Cheers,
- Ole





-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org



Re: [Math] LeastSquaresOptimizer Design

2015-09-24 Thread Luc Maisonobe
Le 24/09/2015 21:40, Ole Ersoy a écrit :
> Hi Luc,
> 
> I gave this some more thought, and I think I may have tapped out to
> soon, even though you are absolutely right about what an exception does
> in terms bubbling execution to a point where it stops or we handle it.
> 
> Suppose we have an Optimizer and an Optimizer observer.  The optimizer
> will emit three different events given in the process of stepping
> through to the max number of iterations it is allotted:
> - SOLUTION_FOUND
> - COULD_NOT_CONVERGE_FOR_REASON_1
> - COULD_NOT_CONVERGE_FOR_REASON_2
> - END (Max iterations reached)
> 
> So we have the observer interface:
> 
> interface OptimizerObserver {
> 
> success(Solution solution)
> update(Enum enum, Optimizer optimizer)
> end(Optimizer optimizer)
> }
> 
> So if the Optimizer notifies the observer of `success`, then the
> observer does what it needs to with the results and moves on.  If the
> observer gets an `update` notification, that means that given the
> current [constraints, numbers of iterations, data] the optimizer cannot
> finish.  But the update method receives the optimizer, so it can adapt
> it, and tell it to continue or just trash it and try something
> completely different.  If the `END` event is reached then the Optimizer
> could not finish given the number of allotted iterations.  The Optimizer
> is passed back via the callback interface so the observer could allow
> more iterations if it wants to...perhaps based on some metric indicating
> how close the optimizer is to finding a solution.
> 
> What this could do is allow the implementation of the observer to throw
> the exception if 'All is lost!', in which case the Optimizer does not
> need an exception.  Totally understand that this may not work
> everywhere, but it seems like it could work in this case.
> 
> WDYT?

With this version, you should also pass the optimizer in case of
success. In most cases, the observer will just ignore it, but in some
cases it may try to solve another problem, or to solve again with
stricter constraints, using the previous solution as the start point
for the more stringent problem. Another case would be to go from a
simple problem to a more difficult problem using some kind of
homotopy.

best regards,
Luc

> 
> Cheers,
> - Ole
> 
> 
> 
> On 09/23/2015 03:09 PM, Luc Maisonobe wrote:
>> Le 23/09/2015 19:20, Ole Ersoy a écrit :
>>> HI Luc,
>> Hi Ole,
>>
>>> On 09/23/2015 03:02 AM, luc wrote:
 Hi,

 Le 2015-09-22 02:55, Ole Ersoy a écrit :
> Hola,
>
> On 09/21/2015 04:15 PM, Gilles wrote:
>> Hi.
>>
>> On Sun, 20 Sep 2015 15:04:08 -0500, Ole Ersoy wrote:
>>> On 09/20/2015 05:51 AM, Gilles wrote:
 On Sun, 20 Sep 2015 01:12:49 -0500, Ole Ersoy wrote:
> Wanted to float some ideas for the LeastSquaresOptimizer (Possibly
> General Optimizer) design.  For example with the
> LevenbergMarquardtOptimizer we would do:
> `LevenbergMarquardtOptimizer.optimize(OptimizationContext c);`
>
> Rough optimize() outline:
> public static void optimise() {
> //perform the optimization
> //If successful
>  c.notify(LevenberMarquardtResultsEnum.SUCCESS, solution);
> //If not successful
>
>
> c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_COST_RELATIVE_TOLERANCE,
>
>
> diagnostic);
> //or
>
>
> c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_PARAMETERS_RELATIVE_TOLERANCE,
>
>
> diagnostic)
> //etc
> }
>
> The diagnostic, when turned on, will contain a trace of the last N
> iterations leading up to the failure.  When turned off, the
> Diagnostic
> instance only contains the parameters used to detect failure. The
> diagnostic could be viewed as an indirect way to log optimizer
> iterations.
>
> WDYT?
 I'm wary of having several different ways to convey information to
 the
 caller.
>>> It would just be one way.
>> One way for optimizer, one way for solvers, one way for ...
> Yes I see what you mean, but I think on a whole it will be worth it to
> add additional sugar code that removes the need for exceptions.
>
>>> But the caller may not be the receiver
>>> (It could be).  The receiver would be an observer attached to the
>>> OptimizationContext that implements an interface allowing it to
>>> observe
>>> the optimization.
>> I'm afraid that it will add to the questions of what to put in the
>> code and how.  [We already had sometimes heated discussions just for
>> the IMHO obvious (e.g. code formatting, documentation,
>> exception...).]
> Hehe.  Yes I remember some of these discussions.  I wonder how much
> time was spent debating the exceptions alone?  Surely everyone must
> have had this 

Re: [Math] LeastSquaresOptimizer Design

2015-09-24 Thread Ole Ersoy



Why should the instance throwing the exception hold a field with the
information?
Separation of concerns: optimizer does the computation,
then the exception holds what's needed for a full report of the failure.

I would see what makes sense on on case by case basis.  For example if the 
Observer, which is implemented by the client / person using CM, realizes that 
it can't continue it can throw an application specific exception using a set of 
Enums that are coded for the application.

if ( optimizer.yourNeverGonnaGetItEver() ) {

   throw new ApplicationSpecificException(ApplicationErrorCodes.PARTYS_OVER, 
optimizer);
}

The error code should be specific enough for the application to understand the 
the optimizer argument is the optimizer (Object type), and then it can 
construct the message from there.



Or the report is done at the observer's level, based on complete
information routinely returned by the optimizer at every step (cf.
previous mail).

I would stick with the same process in this case.

Cheers,
- Ole

-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org



Re: [Math] LeastSquaresOptimizer Design

2015-09-24 Thread Ole Ersoy



On 09/24/2015 06:01 PM, Gilles wrote:

On Thu, 24 Sep 2015 17:02:15 -0500, Ole Ersoy wrote:

On 09/24/2015 03:23 PM, Luc Maisonobe wrote:

Le 24/09/2015 21:40, Ole Ersoy a écrit :

Hi Luc,

I gave this some more thought, and I think I may have tapped out to
soon, even though you are absolutely right about what an exception does
in terms bubbling execution to a point where it stops or we handle it.

Suppose we have an Optimizer and an Optimizer observer.  The optimizer
will emit three different events given in the process of stepping
through to the max number of iterations it is allotted:
- SOLUTION_FOUND
- COULD_NOT_CONVERGE_FOR_REASON_1
- COULD_NOT_CONVERGE_FOR_REASON_2
- END (Max iterations reached)

So we have the observer interface:

interface OptimizerObserver {

 success(Solution solution)
 update(Enum enum, Optimizer optimizer)
 end(Optimizer optimizer)
}

So if the Optimizer notifies the observer of `success`, then the
observer does what it needs to with the results and moves on.  If the
observer gets an `update` notification, that means that given the
current [constraints, numbers of iterations, data] the optimizer cannot
finish.  But the update method receives the optimizer, so it can adapt
it, and tell it to continue or just trash it and try something
completely different.  If the `END` event is reached then the Optimizer
could not finish given the number of allotted iterations. The Optimizer
is passed back via the callback interface so the observer could allow
more iterations if it wants to...perhaps based on some metric indicating
how close the optimizer is to finding a solution.

What this could do is allow the implementation of the observer to throw
the exception if 'All is lost!', in which case the Optimizer does not
need an exception.  Totally understand that this may not work
everywhere, but it seems like it could work in this case.

WDYT?

With this version, you should also pass the optimizer in case of
success. In most cases, the observer will just ignore it, but in some
cases it may try to solve another problem, or to solve again with
stricter constraints, using the previous solution as the start point
for the more stringent problem. Another case would be to go from a
simple problem to a more difficult problem using some kind of
homotopy.

Great - whoooh - glad you like this version a little better - for a
sec I thought I had complete lost it :).


IIUC, I don't like it: it looks like "GOTO"...


Inside the optimizer it would work like this:

while (!done) {
   if (can't converge) {
   observer.update(Enum.CANT_CONVERGE, this);
   }
}

Then in the update method either modify the optimizer's parameters or throw an 
exception.





Note to seeelf ... cancel
therapy with Dr. Phil.  BTW - Gilles - this could also be used as a
light weight logger.


I don't like this either (reinventing the wheel).


You still want me to go and see Dr. Phil? :)





The Optimizer could publish information deemed
interesting on each ITERATION event.


If we'd go for an "OptimizerObserver" that gets called at every
iteration,
there shouldn't be any overlap between it and "Optimizer":

So inside the Optimizer we could have:

while (!done) {
...
if (observer.notifyOnIncrement())
{
observer.increment(this);
}
}

Which would give us an opportunity to cancel the run if, for example, it's not 
converging fast enough.  In that case we set done to true in the observer, and 
then allow the Optimizer to get to the point where it checks if it's done, 
calls the END notification on the observer, and then the observer takes it from 
there.



iteration limit should be dealt with by the observer, the iterative
algorithm would just run "forever" until the observer is satisfied
with the current state (solution is good enough or the allotted
resources - be they time, iterations, evaluations, ... - are
exhausted).


It's possible to do it that way, although I think it's better if that code 
stays on the algorithm such that the Observer interface (The client / person 
using CM implements the Observer) is as simple as possible to implement.


The observer could then be wired
with SLF4J and perform the same type of logging that the Optimizer
would perform.  So CM could declare SLF4J as a test dependency, and
unit tests could log iterations using it.


As a "user", I'm interested in how the algorithms behave on my problem,
not in the CM unit tests.

You could still do that.  I usually take my problem, simplify it down to a data 
set that I think covers all corner cases, and then run it through my unit tests 
while looking at the logging output to get an idea of how my algorithm is 
behaving.



The question remains unanswered: why not use slf4j directly?


FWIU class path dependency conflicts for SLF4J are easily solved by excluding 
logging dependencies that other libraries bring in and then directly depending 
on the logging implementation that you want to use.  So people do run into 

Re: [Math] LeastSquaresOptimizer Design

2015-09-23 Thread Gilles

Hello Luc.

I obviously agree with your main conclusion in that exceptions are 
still
a better alternative to what (we think) we understood from Ole's 
proposal.


However I don't agree about what is a "mess" on the "exception front"
and what is not, and which part of the library is more to blame for
that. :-)

The terse, composite, messages were a middle ground between two 
situations

considered wrong, by one side or the other:
 (1) one exception class per exceptional condition
 (2) one message (to be localized!) per exceptional condition, conveyed 
by

 the same exception class

In the same way that some of Ole's proposals can be handled in a layer
above CM, so could the localization of exception messages.

There is no "huge pile".  There was, before, a lot of duplicated code.
The primary rationale of the "ExceptionContext" was for the 
localization.

It was then reused to avoid (1).

My main point was that an exception type is much more flexible than a
"String".
Assuming that all applications should terminate with the console 
displaying

the error generated by the low-level library is also fairly 80ish. ;-)


Best regards,
Gilles

On Wed, 23 Sep 2015 10:02:30 +0200, luc wrote:

Hi,

Le 2015-09-22 02:55, Ole Ersoy a écrit :

Hola,
On 09/21/2015 04:15 PM, Gilles wrote:

Hi.
On Sun, 20 Sep 2015 15:04:08 -0500, Ole Ersoy wrote:

On 09/20/2015 05:51 AM, Gilles wrote:

On Sun, 20 Sep 2015 01:12:49 -0500, Ole Ersoy wrote:
Wanted to float some ideas for the LeastSquaresOptimizer 
(Possibly

General Optimizer) design.  For example with the
LevenbergMarquardtOptimizer we would do:
`LevenbergMarquardtOptimizer.optimize(OptimizationContext c);`
Rough optimize() outline:
public static void optimise() {
//perform the optimization
//If successful
c.notify(LevenberMarquardtResultsEnum.SUCCESS, solution);
//If not successful


c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_COST_RELATIVE_TOLERANCE,
diagnostic);
//or


c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_PARAMETERS_RELATIVE_TOLERANCE,
diagnostic)
//etc
}
The diagnostic, when turned on, will contain a trace of the last 
N
iterations leading up to the failure.  When turned off, the 
Diagnostic
instance only contains the parameters used to detect failure. 
The

diagnostic could be viewed as an indirect way to log optimizer
iterations.
WDYT?
I'm wary of having several different ways to convey information 
to the

caller.

It would just be one way.

One way for optimizer, one way for solvers, one way for ...
Yes I see what you mean, but I think on a whole it will be worth it 
to

add additional sugar code that removes the need for exceptions.




But the caller may not be the receiver
(It could be).  The receiver would be an observer attached to the
OptimizationContext that implements an interface allowing it to 
observe

the optimization.

I'm afraid that it will add to the questions of what to put in the
code and how.  [We already had sometimes heated discussions just 
for
the IMHO obvious (e.g. code formatting, documentation, 
exception...).]

Hehe.  Yes I remember some of these discussions.  I wonder how much
time was spent debating the exceptions alone?  Surely everyone must
have had this feeling in pit of their stomach that there's got to be 
a

better way.  On the exception topic, these are some of the issues:
I18N
===
If you are new to commons math and thinking about designing a 
commons

math compatible exception you should probably understand the I18N
stuff that's bound to exception (and wonder why it's bound the the
exception).


Not really true. The I18N was really simple at start. See the one 
from
the Orekit project  
which is
still in this state, and you will see adding a new message can be 
done really

simply without a lot of stuff. I18N here is basically one method
(getLocalizedString)
that is never changed in one enumerate class (OrekitMessages), and
adding a message
is only adding one entry to the enumerate, that's all.

The huge pile we have now is only partly related to I18N. The context 
stuff

was introduced as an attempt to solve some programmatic retrieval of
information
at catch time, not related to 18N. The huge hierarchy was introduced 
to
go in a direction were one exception = one type. The ArgUtils was 
introduced

due to some Serialization issues. None of this is 18N.

Yes our exception is crap. No I18N is not the only responsible.


Grab a coffee and spend a few hours, unless you are
obviously fairly new to Java like some ofthe people posting for 
help.
In this case when the exception occurs, there is going to be a lot 
of

tutoring going on on the users list.
Number of Exceptions
===
Before you do actually design a new exception, you should probably 
see

if there is an exception that already fits the category of what you


I don't agree. The large list in the enumerate is only a list of
messages for user display. There would really be 

Re: [Math] LeastSquaresOptimizer Design

2015-09-23 Thread Ole Ersoy

HI Luc,

On 09/23/2015 03:02 AM, luc wrote:

Hi,

Le 2015-09-22 02:55, Ole Ersoy a écrit :

Hola,

On 09/21/2015 04:15 PM, Gilles wrote:

Hi.

On Sun, 20 Sep 2015 15:04:08 -0500, Ole Ersoy wrote:

On 09/20/2015 05:51 AM, Gilles wrote:

On Sun, 20 Sep 2015 01:12:49 -0500, Ole Ersoy wrote:

Wanted to float some ideas for the LeastSquaresOptimizer (Possibly
General Optimizer) design.  For example with the
LevenbergMarquardtOptimizer we would do:
`LevenbergMarquardtOptimizer.optimize(OptimizationContext c);`

Rough optimize() outline:
public static void optimise() {
//perform the optimization
//If successful
c.notify(LevenberMarquardtResultsEnum.SUCCESS, solution);
//If not successful


c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_COST_RELATIVE_TOLERANCE,
diagnostic);
//or


c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_PARAMETERS_RELATIVE_TOLERANCE,
diagnostic)
//etc
}

The diagnostic, when turned on, will contain a trace of the last N
iterations leading up to the failure.  When turned off, the Diagnostic
instance only contains the parameters used to detect failure. The
diagnostic could be viewed as an indirect way to log optimizer
iterations.

WDYT?


I'm wary of having several different ways to convey information to the
caller.

It would just be one way.


One way for optimizer, one way for solvers, one way for ...


Yes I see what you mean, but I think on a whole it will be worth it to
add additional sugar code that removes the need for exceptions.




But the caller may not be the receiver
(It could be).  The receiver would be an observer attached to the
OptimizationContext that implements an interface allowing it to observe
the optimization.


I'm afraid that it will add to the questions of what to put in the
code and how.  [We already had sometimes heated discussions just for
the IMHO obvious (e.g. code formatting, documentation, exception...).]


Hehe.  Yes I remember some of these discussions.  I wonder how much
time was spent debating the exceptions alone?  Surely everyone must
have had this feeling in pit of their stomach that there's got to be a
better way.  On the exception topic, these are some of the issues:

I18N
===
If you are new to commons math and thinking about designing a commons
math compatible exception you should probably understand the I18N
stuff that's bound to exception (and wonder why it's bound the the
exception).


Not really true.

Well a lot of things are gray.  Personally if I'm dealing with an API, I like 
to understand it, so that there are no surprises.  And I understand that the 
I18N coupling might not force me to use it, but if I want to be smart about my 
architecture, and simplify my design, then I should look at it.  Maybe it is a 
good idea.  Maybe I should just gloss over it?  Am I being sloppy if I just 
gloss over it?

Or is there an alternative that provides the same functionality, or maybe 
something better, that does not come with any of these side effects?


The I18N was really simple at start.


Yup I reviewed it and thought - it's probably no big deal - but as I started 
looking into reusing the CM exceptions, I decided that it was not worth the 
complexity.  I think that if I throw and exception it is my responsibility to 
make sure that whomever receives it has a very simple 0 minute or minimal 
resolution time for dealing with it, so that when the code is handed over the 
client feels confident.  It should work like a fridge.  We leave the door open 
too long, a bell goes off, we close the door.


See the one from
the Orekit project  which is
still in this state, and you will see adding a new message can be done really
simply without a lot of stuff.


Simple is a relative term.  But really simple is different from simple.  Really 
simple would be the LevenbergMarquardtOptimizer in it's own module, separated 
from everything else, with a minimal set of dependencies.  If it's not this 
simple, then it quickly grows more complex as we scale.


I18N here is basically one method (getLocalizedString)
that is never changed in one enumerate class (OrekitMessages), and adding a 
message
is only adding one entry to the enumerate, that's all.

Sure and when a developer sees that one method, and they know how sharp the 
Apache people are (Sincerely), they start looking into reusing this design.  So 
if we are going to send them down that path, then that should be the best path.



The huge pile we have now is only partly related to I18N.

That's what I mean by scaling.  It's like the princess with the pea below the 
bottom mattress.  She keeps throwing mattresses on top, and the pea is still 
bothering her.  So after the 10th mattress, she decides they all have to come 
down until she can find out what's going on.  All 10 mattresses have to come 
back off.


The context stuff
was introduced as an attempt to solve some programmatic retrieval of information
at catch time, not related to 18N.

A 

Re: [Math] LeastSquaresOptimizer Design

2015-09-23 Thread Ole Ersoy

Luc,

Just wanted to mention one more thing (On top of the other 325 :) ).  The 
callback design does not bubble exceptions, but we can still get the same 
effect, and do better.  For the app we would define a global error handler and 
make that handler part of each callback. So if are using:

Foo.class
Boo.class
Yao.class

That all all utilize callbacks and each have their own unique set of Enums that 
specify the errors that each class emanates / signals, then the callback would 
delegate these to the global error handler. So effectively we are getting 
exception bubbling, without the ambiguity that comes from having shared 
exceptions across classes.

The global error handler:
1) Gets an error and deals with it
2) Gets and error and signals the user, possibly looking up a message using the 
ErrorEnum.

Cheers,
- Ole

On 09/23/2015 03:02 AM, luc wrote:

Hi,

Le 2015-09-22 02:55, Ole Ersoy a écrit :

Hola,

On 09/21/2015 04:15 PM, Gilles wrote:

Hi.

On Sun, 20 Sep 2015 15:04:08 -0500, Ole Ersoy wrote:

On 09/20/2015 05:51 AM, Gilles wrote:

On Sun, 20 Sep 2015 01:12:49 -0500, Ole Ersoy wrote:

Wanted to float some ideas for the LeastSquaresOptimizer (Possibly
General Optimizer) design.  For example with the
LevenbergMarquardtOptimizer we would do:
`LevenbergMarquardtOptimizer.optimize(OptimizationContext c);`

Rough optimize() outline:
public static void optimise() {
//perform the optimization
//If successful
c.notify(LevenberMarquardtResultsEnum.SUCCESS, solution);
//If not successful


c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_COST_RELATIVE_TOLERANCE,
diagnostic);
//or


c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_PARAMETERS_RELATIVE_TOLERANCE,
diagnostic)
//etc
}

The diagnostic, when turned on, will contain a trace of the last N
iterations leading up to the failure.  When turned off, the Diagnostic
instance only contains the parameters used to detect failure. The
diagnostic could be viewed as an indirect way to log optimizer
iterations.

WDYT?


I'm wary of having several different ways to convey information to the
caller.

It would just be one way.


One way for optimizer, one way for solvers, one way for ...


Yes I see what you mean, but I think on a whole it will be worth it to
add additional sugar code that removes the need for exceptions.




But the caller may not be the receiver
(It could be).  The receiver would be an observer attached to the
OptimizationContext that implements an interface allowing it to observe
the optimization.


I'm afraid that it will add to the questions of what to put in the
code and how.  [We already had sometimes heated discussions just for
the IMHO obvious (e.g. code formatting, documentation, exception...).]


Hehe.  Yes I remember some of these discussions.  I wonder how much
time was spent debating the exceptions alone?  Surely everyone must
have had this feeling in pit of their stomach that there's got to be a
better way.  On the exception topic, these are some of the issues:

I18N
===
If you are new to commons math and thinking about designing a commons
math compatible exception you should probably understand the I18N
stuff that's bound to exception (and wonder why it's bound the the
exception).


Not really true. The I18N was really simple at start. See the one from
the Orekit project  which is
still in this state, and you will see adding a new message can be done really
simply without a lot of stuff. I18N here is basically one method 
(getLocalizedString)
that is never changed in one enumerate class (OrekitMessages), and adding a 
message
is only adding one entry to the enumerate, that's all.

The huge pile we have now is only partly related to I18N. The context stuff
was introduced as an attempt to solve some programmatic retrieval of information
at catch time, not related to 18N. The huge hierarchy was introduced to
go in a direction were one exception = one type. The ArgUtils was introduced
due to some Serialization issues. None of this is 18N.

Yes our exception is crap. No I18N is not the only responsible.


Grab a coffee and spend a few hours, unless you are
obviously fairly new to Java like some ofthe people posting for help.
In this case when the exception occurs, there is going to be a lot of
tutoring going on on the users list.

Number of Exceptions
===
Before you do actually design a new exception, you should probably see
if there is an exception that already fits the category of what you


I don't agree. The large list in the enumerate is only a list of
messages for user display. There would really be nothing wrong to add
even more messages, even if they are close to existing ones. In fact, I
even think we should avoid trying to reuse messages by merging them all
in something not meaningful to users (remember, messages are for display
only). Currently we too often get a message like:

  Number is too large, 3 > 2

Nobody understands this at user level. 

Re: [Math] LeastSquaresOptimizer Design

2015-09-23 Thread luc

Hi,

Le 2015-09-22 02:55, Ole Ersoy a écrit :

Hola,

On 09/21/2015 04:15 PM, Gilles wrote:

Hi.

On Sun, 20 Sep 2015 15:04:08 -0500, Ole Ersoy wrote:

On 09/20/2015 05:51 AM, Gilles wrote:

On Sun, 20 Sep 2015 01:12:49 -0500, Ole Ersoy wrote:

Wanted to float some ideas for the LeastSquaresOptimizer (Possibly
General Optimizer) design.  For example with the
LevenbergMarquardtOptimizer we would do:
`LevenbergMarquardtOptimizer.optimize(OptimizationContext c);`

Rough optimize() outline:
public static void optimise() {
//perform the optimization
//If successful
c.notify(LevenberMarquardtResultsEnum.SUCCESS, solution);
//If not successful


c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_COST_RELATIVE_TOLERANCE,
diagnostic);
//or


c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_PARAMETERS_RELATIVE_TOLERANCE,
diagnostic)
//etc
}

The diagnostic, when turned on, will contain a trace of the last N
iterations leading up to the failure.  When turned off, the 
Diagnostic

instance only contains the parameters used to detect failure. The
diagnostic could be viewed as an indirect way to log optimizer
iterations.

WDYT?


I'm wary of having several different ways to convey information to 
the

caller.

It would just be one way.


One way for optimizer, one way for solvers, one way for ...


Yes I see what you mean, but I think on a whole it will be worth it to
add additional sugar code that removes the need for exceptions.




But the caller may not be the receiver
(It could be).  The receiver would be an observer attached to the
OptimizationContext that implements an interface allowing it to 
observe

the optimization.


I'm afraid that it will add to the questions of what to put in the
code and how.  [We already had sometimes heated discussions just for
the IMHO obvious (e.g. code formatting, documentation, exception...).]


Hehe.  Yes I remember some of these discussions.  I wonder how much
time was spent debating the exceptions alone?  Surely everyone must
have had this feeling in pit of their stomach that there's got to be a
better way.  On the exception topic, these are some of the issues:

I18N
===
If you are new to commons math and thinking about designing a commons
math compatible exception you should probably understand the I18N
stuff that's bound to exception (and wonder why it's bound the the
exception).


Not really true. The I18N was really simple at start. See the one from
the Orekit project  which 
is
still in this state, and you will see adding a new message can be done 
really
simply without a lot of stuff. I18N here is basically one method 
(getLocalizedString)
that is never changed in one enumerate class (OrekitMessages), and 
adding a message

is only adding one entry to the enumerate, that's all.

The huge pile we have now is only partly related to I18N. The context 
stuff
was introduced as an attempt to solve some programmatic retrieval of 
information

at catch time, not related to 18N. The huge hierarchy was introduced to
go in a direction were one exception = one type. The ArgUtils was 
introduced

due to some Serialization issues. None of this is 18N.

Yes our exception is crap. No I18N is not the only responsible.


Grab a coffee and spend a few hours, unless you are
obviously fairly new to Java like some ofthe people posting for help.
In this case when the exception occurs, there is going to be a lot of
tutoring going on on the users list.

Number of Exceptions
===
Before you do actually design a new exception, you should probably see
if there is an exception that already fits the category of what you


I don't agree. The large list in the enumerate is only a list of
messages for user display. There would really be nothing wrong to add
even more messages, even if they are close to existing ones. In fact, I
even think we should avoid trying to reuse messages by merging them all
in something not meaningful to users (remember, messages are for display
only). Currently we too often get a message like:

  Number is too large, 3 > 2

Nobody understands this at user level. The reused message has lost its
signification. I would really prefer different messages for different 
cases
where the fixed part of the format would at least provide some hint to 
the

user.


are doing.  So you start reading.  Exception1...nop
Exception2...nop...Exception3...Exception999..But I think I'm getting
warmer.  OK - Did not find it ... but I'm fairly certain that there is
a elegant place for it somewhere in the exception hierarchy...


I agree. The exception hierarchy is a mess.




Handling of Exceptions
===
If our app uses several of the commons math classes (That throw
exceptions of the same type), and one of those classes throws an
exception,what is the app supposed to do?


It depends on the application. Apache Commons Math is a low level
library it is used in many different contexts and there is no single

Re: [Math] LeastSquaresOptimizer Design

2015-09-23 Thread Luc Maisonobe
Le 23/09/2015 19:20, Ole Ersoy a écrit :
> HI Luc,

Hi Ole,

> 
> On 09/23/2015 03:02 AM, luc wrote:
>> Hi,
>>
>> Le 2015-09-22 02:55, Ole Ersoy a écrit :
>>> Hola,
>>>
>>> On 09/21/2015 04:15 PM, Gilles wrote:
 Hi.

 On Sun, 20 Sep 2015 15:04:08 -0500, Ole Ersoy wrote:
> On 09/20/2015 05:51 AM, Gilles wrote:
>> On Sun, 20 Sep 2015 01:12:49 -0500, Ole Ersoy wrote:
>>> Wanted to float some ideas for the LeastSquaresOptimizer (Possibly
>>> General Optimizer) design.  For example with the
>>> LevenbergMarquardtOptimizer we would do:
>>> `LevenbergMarquardtOptimizer.optimize(OptimizationContext c);`
>>>
>>> Rough optimize() outline:
>>> public static void optimise() {
>>> //perform the optimization
>>> //If successful
>>> c.notify(LevenberMarquardtResultsEnum.SUCCESS, solution);
>>> //If not successful
>>>
>>>
>>> c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_COST_RELATIVE_TOLERANCE,
>>>
>>> diagnostic);
>>> //or
>>>
>>>
>>> c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_PARAMETERS_RELATIVE_TOLERANCE,
>>>
>>> diagnostic)
>>> //etc
>>> }
>>>
>>> The diagnostic, when turned on, will contain a trace of the last N
>>> iterations leading up to the failure.  When turned off, the
>>> Diagnostic
>>> instance only contains the parameters used to detect failure. The
>>> diagnostic could be viewed as an indirect way to log optimizer
>>> iterations.
>>>
>>> WDYT?
>>
>> I'm wary of having several different ways to convey information to
>> the
>> caller.
> It would just be one way.

 One way for optimizer, one way for solvers, one way for ...
>>>
>>> Yes I see what you mean, but I think on a whole it will be worth it to
>>> add additional sugar code that removes the need for exceptions.
>>>

> But the caller may not be the receiver
> (It could be).  The receiver would be an observer attached to the
> OptimizationContext that implements an interface allowing it to
> observe
> the optimization.

 I'm afraid that it will add to the questions of what to put in the
 code and how.  [We already had sometimes heated discussions just for
 the IMHO obvious (e.g. code formatting, documentation, exception...).]
>>>
>>> Hehe.  Yes I remember some of these discussions.  I wonder how much
>>> time was spent debating the exceptions alone?  Surely everyone must
>>> have had this feeling in pit of their stomach that there's got to be a
>>> better way.  On the exception topic, these are some of the issues:
>>>
>>> I18N
>>> ===
>>> If you are new to commons math and thinking about designing a commons
>>> math compatible exception you should probably understand the I18N
>>> stuff that's bound to exception (and wonder why it's bound the the
>>> exception).
>>
>> Not really true.
> Well a lot of things are gray.  Personally if I'm dealing with an API, I
> like to understand it, so that there are no surprises.  And I understand
> that the I18N coupling might not force me to use it, but if I want to be
> smart about my architecture, and simplify my design, then I should look
> at it.  Maybe it is a good idea.  Maybe I should just gloss over it?  Am
> I being sloppy if I just gloss over it?
> 
> Or is there an alternative that provides the same functionality, or
> maybe something better, that does not come with any of these side effects?
> 
>> The I18N was really simple at start.
> 
> Yup I reviewed it and thought - it's probably no big deal - but as I
> started looking into reusing the CM exceptions, I decided that it was
> not worth the complexity.  I think that if I throw and exception it is
> my responsibility to make sure that whomever receives it has a very
> simple 0 minute or minimal resolution time for dealing with it, so that
> when the code is handed over the client feels confident.  It should work
> like a fridge.  We leave the door open too long, a bell goes off, we
> close the door.
> 
>> See the one from
>> the Orekit project 
>> which is
>> still in this state, and you will see adding a new message can be done
>> really
>> simply without a lot of stuff.
> 
> Simple is a relative term.  But really simple is different from simple. 
> Really simple would be the LevenbergMarquardtOptimizer in it's own
> module, separated from everything else, with a minimal set of
> dependencies.  If it's not this simple, then it quickly grows more
> complex as we scale.
> 
>> I18N here is basically one method (getLocalizedString)
>> that is never changed in one enumerate class (OrekitMessages), and
>> adding a message
>> is only adding one entry to the enumerate, that's all.
> Sure and when a developer sees that one method, and they know how sharp
> the Apache people are (Sincerely), they start looking into reusing this
> design.  So if we are going to send them down 

Re: [Math] LeastSquaresOptimizer Design

2015-09-23 Thread Gilles

[...]

CM is not intended to be a design pattern people should mimic.
We are so bad at this


The crux is that the project's team is in effect not _interested_
in this.  [And I admit that I had not understood it for a long
time (hence the temptation to convince that it was important for
*some* people).]


it would be a shame. No one in its right mind would copy
or reuse this stuff. It is for internal use only


Then why is it so difficult to change (cf. all the nit-picking
about backward-compatibility)?
As was (relatively) recently discussed, we could "mark" some code
"for internal use" and be free to break compatibility at any time,
for the sake of (an attempt at) a better design.


and we don't even have
the resources to manage it by ourselves


There are (maybe) other people (like Ole?) who would like to
experiment with new design ideas (not new math algorithms!)
but are repelled by the (overly) conservative development process
which is mainly feature-driven (like in a commercial project,
shall I dare to say).


so we can't consider it as a
path people should follow as we are leading them. Here we would be
leading them directly against the wall.


True, unfortunately.
There is really no long-term design. Even short term (quasi-)decisions
when they concern the library as a whole, are not followed by action
(cf. "fluent API")...


[...]


Best,
Gilles


-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org



Re: [Math] LeastSquaresOptimizer Design

2015-09-23 Thread Ole Ersoy

On 09/23/2015 03:09 PM, Luc Maisonobe wrote:
CM is not intended to be a design pattern people should mimic. We are so bad at this it would be a shame. No one in its right mind would copy or reuse this stuff. It is for internal use only and we don't even have the resources to manage it by ourselves so we can't consider it as a path people should follow as we are leading them. Here we would be leading them directly against the wall. 


Hehe - I think that's like Michael Jordan saying - "Guys, don't try to be like me.  
I just play a little ball.  Dunk from the free throw line.  Six world championships, but 
THATs it!".  In any case, I really appreciate you and Gilles taking the time to 
talk.  Luc (And possibly Gilles) - I can actually see why you are getting a bit annoyed, 
because I'm ignoring something important.

I've been doing 90% NodeJS stuff lately (Which is event loop based and relies 
callbacks) so I forgot one very important thing that I think you have both 
tried to tell me.  The exception undoes the current callstack / breaks the 
current program flow, bubbling up to the handler.  Thts a good point.

OK - So scratch the callback thinking for synchronous code.  The Lombok stuff 
should still be good though and hopefully some of the callback discussion 
around and asynchronous option - I hope!  Geez.

What do you think about having one exception per class with an Enum that 
encodes the various types of exceptional conditions that the class can find 
itself in?  So in the case of LevenbergMarquardtOptimizer there would be a:
- LevenbergMarquardtOptimizerException:
- LevenbergMarquardtOptimizerExceptionEnum

When the exception is thrown it sets the Enum indicating the root cause.  The 
enum can then be used as a key to lookup the corresponding message.

Any better?

Cheers,
- Ole


-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org



Re: [Math] LeastSquaresOptimizer Design

2015-09-22 Thread Ole Ersoy

One more thing - This is separate from the other stuff.  The LMOptimizer has 
several configuration properties, with corresponding getters and a 
corresponding with() API.  It would be good if these existed on their own class 
that used Lombok (https://projectlombok.org/) to generate (Byte code) the fluid 
API and the getters.  That would eliminate and estimated 40% of the source 
code.  Lombok annotations, such as @NonNull, could be used to generate NPE 
checks in the configuration instance.  This way CM does not have to check for 
NPEs anymore.  The will be thrown when the configuration instance is 
constructed.

This is one reason I was thinking it might be useful to have an context holding 
things like:
- configuration
- callback
- problem

But I think it's fine if these are passed in separately as well. It's cleaner 
to call callback.notify() than context.callback.notify().

Cheers,
- Ole


On 09/22/2015 06:46 AM, Gilles wrote:

Hi.

On Mon, 21 Sep 2015 19:55:15 -0500, Ole Ersoy wrote:

Hola,

On 09/21/2015 04:15 PM, Gilles wrote:

Hi.

On Sun, 20 Sep 2015 15:04:08 -0500, Ole Ersoy wrote:

On 09/20/2015 05:51 AM, Gilles wrote:

On Sun, 20 Sep 2015 01:12:49 -0500, Ole Ersoy wrote:

Wanted to float some ideas for the LeastSquaresOptimizer (Possibly
General Optimizer) design.  For example with the
LevenbergMarquardtOptimizer we would do:
`LevenbergMarquardtOptimizer.optimize(OptimizationContext c);`

Rough optimize() outline:
public static void optimise() {
//perform the optimization
//If successful
c.notify(LevenberMarquardtResultsEnum.SUCCESS, solution);
//If not successful



c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_COST_RELATIVE_TOLERANCE,
diagnostic);
//or



c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_PARAMETERS_RELATIVE_TOLERANCE,
diagnostic)
//etc
}

The diagnostic, when turned on, will contain a trace of the last N
iterations leading up to the failure.  When turned off, the Diagnostic
instance only contains the parameters used to detect failure. The
diagnostic could be viewed as an indirect way to log optimizer
iterations.

WDYT?


I'm wary of having several different ways to convey information to the
caller.

It would just be one way.


One way for optimizer, one way for solvers, one way for ...


Yes I see what you mean, but I think on a whole it will be worth it
to add additional sugar code that removes the need for exceptions.


Isn't always possible to wrap exception-generating code so that upper
layers do not see them?
The interface would have to know how to handle them and propagate the
information in some other form (callback).




But the caller may not be the receiver
(It could be).  The receiver would be an observer attached to the
OptimizationContext that implements an interface allowing it to observe
the optimization.


I'm afraid that it will add to the questions of what to put in the
code and how.  [We already had sometimes heated discussions just for
the IMHO obvious (e.g. code formatting, documentation, exception...).]


Hehe.  Yes I remember some of these discussions.  I wonder how much
time was spent debating the exceptions alone?  Surely everyone must
have had this feeling in pit of their stomach that there's got to be a
better way.  On the exception topic, these are some of the issues:

I18N
===
If you are new to commons math and thinking about designing a commons
math compatible exception you should probably understand the I18N
stuff that's bound to exception (and wonder why it's bound the the
exception).  Grab a coffee and spend a few hours, unless you are
obviously fairly new to Java like some ofthe people posting for help.
In this case when the exception occurs, there is going to be a lot of
tutoring going on on the users list.


I already said all I had to say about this; it's in the archive.
Summary: I agree that it shouldn't be here.


Number of Exceptions
===
Before you do actually design a new exception, you should probably
see if there is an exception that already fits the category of what
you are doing.  So you start reading.  Exception1...nop
Exception2...nop...Exception3...Exception999..But I think I'm getting
warmer.  OK - Did not find it ... but I'm fairly certain that there is
a elegant place for it somewhere in the exception hierarchy...


On this, I also explained at length my views (assuming that exceptions
are part of the design).
Summary: an exception indicates that something went wrong, and the caller
should not hope to get anything good out of the call that raised the
exception (i.e. he _must_ craft another call that meets the requirements
of the code).


Handling of Exceptions
===
If our app uses several of the commons math classes (That throw
exceptions of the same type), and one of those classes throws an
exception,what is the app supposed to do?


Cf. previous paragraph.


I think most developers would find that question somewhat
challenging.  There are numerous strategies.  Catch all 

Re: [Math] LeastSquaresOptimizer Design

2015-09-22 Thread Gilles

Hi.

On Mon, 21 Sep 2015 19:55:15 -0500, Ole Ersoy wrote:

Hola,

On 09/21/2015 04:15 PM, Gilles wrote:

Hi.

On Sun, 20 Sep 2015 15:04:08 -0500, Ole Ersoy wrote:

On 09/20/2015 05:51 AM, Gilles wrote:

On Sun, 20 Sep 2015 01:12:49 -0500, Ole Ersoy wrote:
Wanted to float some ideas for the LeastSquaresOptimizer 
(Possibly

General Optimizer) design.  For example with the
LevenbergMarquardtOptimizer we would do:
`LevenbergMarquardtOptimizer.optimize(OptimizationContext c);`

Rough optimize() outline:
public static void optimise() {
//perform the optimization
//If successful
c.notify(LevenberMarquardtResultsEnum.SUCCESS, solution);
//If not successful



c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_COST_RELATIVE_TOLERANCE,
diagnostic);
//or



c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_PARAMETERS_RELATIVE_TOLERANCE,
diagnostic)
//etc
}

The diagnostic, when turned on, will contain a trace of the last 
N
iterations leading up to the failure.  When turned off, the 
Diagnostic

instance only contains the parameters used to detect failure. The
diagnostic could be viewed as an indirect way to log optimizer
iterations.

WDYT?


I'm wary of having several different ways to convey information to 
the

caller.

It would just be one way.


One way for optimizer, one way for solvers, one way for ...


Yes I see what you mean, but I think on a whole it will be worth it
to add additional sugar code that removes the need for exceptions.


Isn't always possible to wrap exception-generating code so that upper
layers do not see them?
The interface would have to know how to handle them and propagate the
information in some other form (callback).




But the caller may not be the receiver
(It could be).  The receiver would be an observer attached to the
OptimizationContext that implements an interface allowing it to 
observe

the optimization.


I'm afraid that it will add to the questions of what to put in the
code and how.  [We already had sometimes heated discussions just for
the IMHO obvious (e.g. code formatting, documentation, 
exception...).]


Hehe.  Yes I remember some of these discussions.  I wonder how much
time was spent debating the exceptions alone?  Surely everyone must
have had this feeling in pit of their stomach that there's got to be 
a

better way.  On the exception topic, these are some of the issues:

I18N
===
If you are new to commons math and thinking about designing a commons
math compatible exception you should probably understand the I18N
stuff that's bound to exception (and wonder why it's bound the the
exception).  Grab a coffee and spend a few hours, unless you are
obviously fairly new to Java like some ofthe people posting for help.
In this case when the exception occurs, there is going to be a lot of
tutoring going on on the users list.


I already said all I had to say about this; it's in the archive.
Summary: I agree that it shouldn't be here.


Number of Exceptions
===
Before you do actually design a new exception, you should probably
see if there is an exception that already fits the category of what
you are doing.  So you start reading.  Exception1...nop
Exception2...nop...Exception3...Exception999..But I think I'm getting
warmer.  OK - Did not find it ... but I'm fairly certain that there 
is

a elegant place for it somewhere in the exception hierarchy...


On this, I also explained at length my views (assuming that exceptions
are part of the design).
Summary: an exception indicates that something went wrong, and the 
caller

should not hope to get anything good out of the call that raised the
exception (i.e. he _must_ craft another call that meets the 
requirements

of the code).


Handling of Exceptions
===
If our app uses several of the commons math classes (That throw
exceptions of the same type), and one of those classes throws an
exception,what is the app supposed to do?


Cf. previous paragraph.


I think most developers would find that question somewhat
challenging.  There are numerous strategies.  Catch all exceptions 
and

log what happened, etc.  But what if the requirement is that if an
exception is thrown, the organization that receives it has 0 seconds
to get to the root cause of it and understand the dynamics. Is this
doable?  (Yes obviously, but how hard is it...?).


Cf. previous paragraph.
In effect, you describe an upper layer's requirement (handling an 
expected
"unexpected(!) failure"). IMHO, it's out CM's realm (CM raises the 
exception,

end of story).


It seems that the reporting interfaces could quickly overwhelm
the "actual" code (one type of context per algorithm).

There would one type of Observer interface per algorithm.  It would
act on the solution and what are currently exceptions, although 
these

would be translated into enums.


Unless I'm mistaken, the most common use-case for codes implemented
in a library such as CM is to provide a correct answer or bail out
in a non-equivocal way.

Most 

Re: [Math] LeastSquaresOptimizer Design

2015-09-22 Thread Ole Ersoy

On 09/22/2015 06:46 AM, Gilles wrote:

Hi.

On Mon, 21 Sep 2015 19:55:15 -0500, Ole Ersoy wrote:

Hola,

On 09/21/2015 04:15 PM, Gilles wrote:

Hi.

On Sun, 20 Sep 2015 15:04:08 -0500, Ole Ersoy wrote:

On 09/20/2015 05:51 AM, Gilles wrote:

On Sun, 20 Sep 2015 01:12:49 -0500, Ole Ersoy wrote:

Wanted to float some ideas for the LeastSquaresOptimizer (Possibly
General Optimizer) design.  For example with the
LevenbergMarquardtOptimizer we would do:
`LevenbergMarquardtOptimizer.optimize(OptimizationContext c);`

Rough optimize() outline:
public static void optimise() {
//perform the optimization
//If successful
c.notify(LevenberMarquardtResultsEnum.SUCCESS, solution);
//If not successful



c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_COST_RELATIVE_TOLERANCE,
diagnostic);
//or



c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_PARAMETERS_RELATIVE_TOLERANCE,
diagnostic)
//etc
}

The diagnostic, when turned on, will contain a trace of the last N
iterations leading up to the failure.  When turned off, the Diagnostic
instance only contains the parameters used to detect failure. The
diagnostic could be viewed as an indirect way to log optimizer
iterations.

WDYT?


I'm wary of having several different ways to convey information to the
caller.

It would just be one way.


One way for optimizer, one way for solvers, one way for ...


Yes I see what you mean, but I think on a whole it will be worth it
to add additional sugar code that removes the need for exceptions.


Isn't always possible to wrap exception-generating code so that upper
layers do not see them?

The layer that calls the commons math function will see errors through the 
callback interface.  They are not exceptions though. The error is encoded as an 
Enum and is specific to the calling code...not generic across multiple classes.



The interface would have to know how to handle them and propagate the
information in some other form (callback).

Yes I think now we are saying the same thing.






But the caller may not be the receiver
(It could be).  The receiver would be an observer attached to the
OptimizationContext that implements an interface allowing it to observe
the optimization.


I'm afraid that it will add to the questions of what to put in the
code and how.  [We already had sometimes heated discussions just for
the IMHO obvious (e.g. code formatting, documentation, exception...).]


Hehe.  Yes I remember some of these discussions.  I wonder how much
time was spent debating the exceptions alone?  Surely everyone must
have had this feeling in pit of their stomach that there's got to be a
better way.  On the exception topic, these are some of the issues:

I18N
===
If you are new to commons math and thinking about designing a commons
math compatible exception you should probably understand the I18N
stuff that's bound to exception (and wonder why it's bound the the
exception).  Grab a coffee and spend a few hours, unless you are
obviously fairly new to Java like some ofthe people posting for help.
In this case when the exception occurs, there is going to be a lot of
tutoring going on on the users list.


I already said all I had to say about this; it's in the archive.
Summary: I agree that it shouldn't be here.


Number of Exceptions
===
Before you do actually design a new exception, you should probably
see if there is an exception that already fits the category of what
you are doing.  So you start reading.  Exception1...nop
Exception2...nop...Exception3...Exception999..But I think I'm getting
warmer.  OK - Did not find it ... but I'm fairly certain that there is
a elegant place for it somewhere in the exception hierarchy...


On this, I also explained at length my views (assuming that exceptions
are part of the design).
Summary: an exception indicates that something went wrong, and the caller
should not hope to get anything good out of the call that raised the
exception (i.e. he _must_ craft another call that meets the requirements
of the code).


And further down it is noted that if the caller wants to deal with the 
exceptions directly based on the call then the caller can create a wrapper for 
each commons math function throwing the exception.  So the most elegant way of 
doing this is probably one wrapper per class.  And the interface for the 
wrapper is left up to the designer.

Or we could get rid of the exceptions, design a callback interface for each 
solver / optimizer / etc.  They should be pretty similar across commons math.  
In general they have two methods:

success(solution);
error(Enum.CODE, [Diagnostics])

Enum.CODE would be used for I18N.

The Diagnostics are optional, but I would say at a minimum at propagate the 
same information that exceptions are propagating now.


Handling of Exceptions
===
If our app uses several of the commons math classes (That throw
exceptions of the same type), and one of those classes throws an
exception,what is the app supposed to do?


Cf. 

Re: [Math] LeastSquaresOptimizer Design

2015-09-21 Thread Ole Ersoy

Hola,

On 09/21/2015 04:15 PM, Gilles wrote:

Hi.

On Sun, 20 Sep 2015 15:04:08 -0500, Ole Ersoy wrote:

On 09/20/2015 05:51 AM, Gilles wrote:

On Sun, 20 Sep 2015 01:12:49 -0500, Ole Ersoy wrote:

Wanted to float some ideas for the LeastSquaresOptimizer (Possibly
General Optimizer) design.  For example with the
LevenbergMarquardtOptimizer we would do:
`LevenbergMarquardtOptimizer.optimize(OptimizationContext c);`

Rough optimize() outline:
public static void optimise() {
//perform the optimization
//If successful
c.notify(LevenberMarquardtResultsEnum.SUCCESS, solution);
//If not successful


c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_COST_RELATIVE_TOLERANCE,
diagnostic);
//or


c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_PARAMETERS_RELATIVE_TOLERANCE,
diagnostic)
//etc
}

The diagnostic, when turned on, will contain a trace of the last N
iterations leading up to the failure.  When turned off, the Diagnostic
instance only contains the parameters used to detect failure. The
diagnostic could be viewed as an indirect way to log optimizer
iterations.

WDYT?


I'm wary of having several different ways to convey information to the
caller.

It would just be one way.


One way for optimizer, one way for solvers, one way for ...


Yes I see what you mean, but I think on a whole it will be worth it to add 
additional sugar code that removes the need for exceptions.




But the caller may not be the receiver
(It could be).  The receiver would be an observer attached to the
OptimizationContext that implements an interface allowing it to observe
the optimization.


I'm afraid that it will add to the questions of what to put in the
code and how.  [We already had sometimes heated discussions just for
the IMHO obvious (e.g. code formatting, documentation, exception...).]


Hehe.  Yes I remember some of these discussions.  I wonder how much time was 
spent debating the exceptions alone?  Surely everyone must have had this 
feeling in pit of their stomach that there's got to be a better way.  On the 
exception topic, these are some of the issues:

I18N
===
If you are new to commons math and thinking about designing a commons math 
compatible exception you should probably understand the I18N stuff that's bound 
to exception (and wonder why it's bound the the exception).  Grab a coffee and 
spend a few hours, unless you are obviously fairly new to Java like some ofthe 
people posting for help.  In this case when the exception occurs, there is 
going to be a lot of tutoring going on on the users list.

Number of Exceptions
===
Before you do actually design a new exception, you should probably see if there 
is an exception that already fits the category of what you are doing.  So you 
start reading.  Exception1...nop 
Exception2...nop...Exception3...Exception999..But I think I'm getting warmer.  
OK - Did not find it ... but I'm fairly certain that there is a elegant place 
for it somewhere in the exception hierarchy...


Handling of Exceptions
===
If our app uses several of the commons math classes (That throw exceptions of 
the same type), and one of those classes throws an exception,what is the app 
supposed to do?

I think most developers would find that question somewhat challenging.  There 
are numerous strategies.  Catch all exceptions and log what happened, etc.  But 
what if the requirement is that if an exception is thrown, the organization 
that receives it has 0 seconds to get to the root cause of it and understand 
the dynamics. Is this doable?  (Yes obviously, but how hard is it...?).



It seems that the reporting interfaces could quickly overwhelm
the "actual" code (one type of context per algorithm).

There would one type of Observer interface per algorithm.  It would
act on the solution and what are currently exceptions, although these
would be translated into enums.


Unless I'm mistaken, the most common use-case for codes implemented
in a library such as CM is to provide a correct answer or bail out
in a non-equivocal way.

Most java developers are used to synchronous coding...call the method get the 
response...catch the exception if needed.  This is changing with JDK8, and as 
we evolve and start using lambdas, we become more accustomed to the functional 
callback style of programming.  Personally I want to be able to use an API that 
gives me what I need when everything works as expected, allows me to resolve 
unexpected issues with minimal effort, and is as simple, fluid, and lightweight 
as possible.



It would make the code more involved to handle a minority of
(undefined) cases. [Actual examples would be welcome in order to
focus the discussion.]


Rough Outline (I've evolved the concept and moved away from the 
OptimizationContext in the process of writing):

interface LevenbergMarquardtObserver {

public void hola(Solution s);
public void sugarHoneyIceTea(ResultType rt, Dianostics d);
}

public class LMObserver implements 

Re: [Math] LeastSquaresOptimizer Design

2015-09-21 Thread Gilles

Hi.

On Sun, 20 Sep 2015 15:04:08 -0500, Ole Ersoy wrote:

On 09/20/2015 05:51 AM, Gilles wrote:

On Sun, 20 Sep 2015 01:12:49 -0500, Ole Ersoy wrote:

Wanted to float some ideas for the LeastSquaresOptimizer (Possibly
General Optimizer) design.  For example with the
LevenbergMarquardtOptimizer we would do:
`LevenbergMarquardtOptimizer.optimize(OptimizationContext c);`

Rough optimize() outline:
public static void optimise() {
//perform the optimization
//If successful
c.notify(LevenberMarquardtResultsEnum.SUCCESS, solution);
//If not successful


c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_COST_RELATIVE_TOLERANCE,
diagnostic);
//or


c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_PARAMETERS_RELATIVE_TOLERANCE,
diagnostic)
//etc
}

The diagnostic, when turned on, will contain a trace of the last N
iterations leading up to the failure.  When turned off, the 
Diagnostic

instance only contains the parameters used to detect failure. The
diagnostic could be viewed as an indirect way to log optimizer
iterations.

WDYT?


I'm wary of having several different ways to convey information to 
the

caller.

It would just be one way.


One way for optimizer, one way for solvers, one way for ...


But the caller may not be the receiver
(It could be).  The receiver would be an observer attached to the
OptimizationContext that implements an interface allowing it to 
observe

the optimization.


I'm afraid that it will add to the questions of what to put in the
code and how.  [We already had sometimes heated discussions just for
the IMHO obvious (e.g. code formatting, documentation, exception...).]


It seems that the reporting interfaces could quickly overwhelm
the "actual" code (one type of context per algorithm).

There would one type of Observer interface per algorithm.  It would
act on the solution and what are currently exceptions, although these
would be translated into enums.


Unless I'm mistaken, the most common use-case for codes implemented
in a library such as CM is to provide a correct answer or bail out
in a non-equivocal way.

It would make the code more involved to handle a minority of
(undefined) cases. [Actual examples would be welcome in order to
focus the discussion.]


The current reporting is based on exceptions, and assumes that if no
exception was thrown, then the user's request completed 
successfully.

Sure - personally I'd much rather deal with something similar to an
HTTP status code in a callback, than an exception .  I think the code
is cleaner and the calback makes it more elegant to apply an adaptive
approach to handling the response, like slightly relaxing 
constraints,

convergence parameters, etc.  Also by getting rid of the exceptions,
we no longer depend on the I18N layer that they are tied to and now
the messages can be more informative, since they target the root
cause.  The observer can also run in the 'main' thread' while the
optimization can run asynchronously.  Also WRT JDK9 and modules,
loosing the exceptions would mean one less dependency when the 
library

is up into JDK9 modules...which would be more in line with this
philosophy:
https://github.com/substack/browserify-handbook#module-philosophy


I'm not sure I fully understood the philosophy from the text in this
short paragraph.
But I do not agree with the idea that the possibility to quickly find
some code is more important than standards and best practices.


I totally agree that in some circumstances, more information on the
inner working of an algorithm would be quite useful.

... Algorithm iterations become unit testable.


But I don't see the point in devoting resources to reinvent the 
wheel:

You mean pimping the wheel?  Big pimpin.


I think that logging statements are easy to add, not disruptive at all,
and come in handy to understand a code's unexpected behaviour.
Assuming that a "logging" feature is useful, it can be added *now* 
using

a dependency towards a weight-less (!) framework such as "slf4j".
IMO, it would be a waste of time to implement a new communication layer
that can do that, and more, if it would be used for logging only in 99%
of the cases.



I longed several times for the use of a logging library.
The only show-stopper has been the informal "no-dependency" 
policy...

JDK9 Jigsaw should solve dependency hell, so the less coupling
between commons math classes the better.


I wouldn't call "coupling" the dependency towards exception classes:
they are little utilities that can make sense in various parts of the
library.

[Unless one wants to embark on yet another discussion about exceptions;
whether there should be one class for each of the "messages" that exist
in "LocalizedFormats"; whether localization should be done in CM;
etc.]


Anyways I'm obviously
interested in playing with this stuff, so when I get something up 
into

a repository I'll to do a callback :).


If you are interested in big overhauls, there is one that gathered
relative consensus: rewrite the algorithms in a 

Re: [Math] LeastSquaresOptimizer Design

2015-09-20 Thread Gilles

On Sun, 20 Sep 2015 01:12:49 -0500, Ole Ersoy wrote:

Wanted to float some ideas for the LeastSquaresOptimizer (Possibly
General Optimizer) design.  For example with the
LevenbergMarquardtOptimizer we would do:
`LevenbergMarquardtOptimizer.optimize(OptimizationContext c);`

Rough optimize() outline:
public static void optimise() {
//perform the optimization
//If successful
c.notify(LevenberMarquardtResultsEnum.SUCCESS, solution);
//If not successful

c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_COST_RELATIVE_TOLERANCE,
diagnostic);
//or

c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_PARAMETERS_RELATIVE_TOLERANCE,
diagnostic)
//etc
}

The diagnostic, when turned on, will contain a trace of the last N
iterations leading up to the failure.  When turned off, the 
Diagnostic

instance only contains the parameters used to detect failure.  The
diagnostic could be viewed as an indirect way to log optimizer
iterations.

WDYT?


I'm wary of having several different ways to convey information to the
caller. It seems that the reporting interfaces could quickly overwhelm
the "actual" code (one type of context per algorithm).

The current reporting is based on exceptions, and assumes that if no
exception was thrown, then the user's request completed successfully.
I totally agree that in some circumstances, more information on the
inner working of an algorithm would be quite useful.

But I don't see the point in devoting resources to reinvent the wheel:
I longed several times for the use of a logging library.
The only show-stopper has been the informal "no-dependency" policy...

Best rgards,
Gilles


-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org



Re: [Math] LeastSquaresOptimizer Design

2015-09-20 Thread Ole Ersoy



On 09/20/2015 05:51 AM, Gilles wrote:

On Sun, 20 Sep 2015 01:12:49 -0500, Ole Ersoy wrote:

Wanted to float some ideas for the LeastSquaresOptimizer (Possibly
General Optimizer) design.  For example with the
LevenbergMarquardtOptimizer we would do:
`LevenbergMarquardtOptimizer.optimize(OptimizationContext c);`

Rough optimize() outline:
public static void optimise() {
//perform the optimization
//If successful
c.notify(LevenberMarquardtResultsEnum.SUCCESS, solution);
//If not successful

c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_COST_RELATIVE_TOLERANCE,
diagnostic);
//or

c.notify(LevenberMarquardtResultsEnum.TOO_SMALL_PARAMETERS_RELATIVE_TOLERANCE,
diagnostic)
//etc
}

The diagnostic, when turned on, will contain a trace of the last N
iterations leading up to the failure.  When turned off, the Diagnostic
instance only contains the parameters used to detect failure. The
diagnostic could be viewed as an indirect way to log optimizer
iterations.

WDYT?


I'm wary of having several different ways to convey information to the
caller. 

It would just be one way.  But the caller may not be the receiver (It could 
be).  The receiver would be an observer attached to the OptimizationContext 
that implements an interface allowing it to observe the optimization.

It seems that the reporting interfaces could quickly overwhelm
the "actual" code (one type of context per algorithm).

There would one type of Observer interface per algorithm.  It would act on the 
solution and what are currently exceptions, although these would be translated 
into enums.

The current reporting is based on exceptions, and assumes that if no
exception was thrown, then the user's request completed successfully.

Sure - personally I'd much rather deal with something similar to an HTTP status 
code in a callback, than an exception .  I think the code is cleaner and the 
calback makes it more elegant to apply an adaptive approach to handling the 
response, like slightly relaxing constraints, convergence parameters, etc.  
Also by getting rid of the exceptions, we no longer depend on the I18N layer 
that they are tied to and now the messages can be more informative, since they 
target the root cause.  The observer can also run in the 'main' thread' while 
the optimization can run asynchronously.  Also WRT JDK9 and modules, loosing 
the exceptions would mean one less dependency when the library is up into JDK9 
modules...which would be more in line with this philosophy:
https://github.com/substack/browserify-handbook#module-philosophy


I totally agree that in some circumstances, more information on the
inner working of an algorithm would be quite useful.

... Algorithm iterations become unit testable.


But I don't see the point in devoting resources to reinvent the wheel:

You mean pimping the wheel?  Big pimpin.


I longed several times for the use of a logging library.
The only show-stopper has been the informal "no-dependency" policy...

JDK9 Jigsaw should solve dependency hell, so the less coupling between commons 
math classes the better.  Anyways I'm obviously interested in playing with this 
stuff, so when I get something up into a repository I'll to do a callback :).

Cheers,
Ole


-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org