You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by "Mark R. Diggory" <md...@latte.harvard.edu> on 2003/06/25 04:57:31 UTC

[math][functor] More Design Concerns

(1) Overview of the library design to date

[analysis]:
Uses Objectified "Functions", or "Functors" these objects resemble the 
same approach used in the Commons sandbox Functor package.

[stats]:
Univariate use what amount to "Data Beans" with get/set style methods,
StatUtils provide easy static access focal point.
TestStatistic provides Bi/Multivariate Statistical tests as functions.
Distributions are a mix of bean and objects math evaluation methods.

[linear]:
Approaches a OOD that provides math function methods like RealMatrix 
add(RealMatrix m).

[random]:
Amounts to a random "value server" or "value iterator" design.

[special]:
Static Beta and Gamma distribution utilities.

[util]:
DoubleArray "Wrapper/Collection" tools and ContinuedFraction data 
structure. MthUtils is another Static method focal point.


How many models do we currently have? Three:

*Functors* Objects that act as Math Functions, taking data as input, 
providing data output. Example:

public interface UnivariateRealFunction {

     public double value(double x) throws MathException; {



*Beans* Objects with getters/setters Example:

public Interface Univariate {

     public double getMean();


*Straight Class* Objects with functional methods that evaluate to a 
result. Example:

public interface RealMatrix {

     public RealMatrix add(RealMatrix m) throws IllegalArgumentException;


(2) Considerations

a.) Is consistent library design important? Can all these models 
interace effectively? Are all these different design models required? Is 
there a single design model that can span the entire library?

b.) Which design strategy is of more interest to the project? Small 
compact classes used to complete one specific task, where the 
programming is primarily OOD in nature? or Feature rich interfaces that 
encapsulate full ranges of functionality, where programming is primarily 
"procedural" in nature?

c.) What is the platform of interest for [math]? Server Side or 
Application.

d.) Should static method utilities be avoided at all costs in both 
cases? OR are there specific situations were static functions do not 
create garbage collection considerations and issues (like, when only 
returning primitives).


(3.) A couple proposals:

(i.) Brent and Pietschmann can you make suggestions/recommendations as 
to how your "function object" model could be applied to StaticUtil 
situations? Are you familiar with the Functors project and is there a 
possibility that they should be considered as the basic design strategy 
or base of implementation for your "Function Object" design? if they are 
a Commons project as well is there a possible dependency here we could 
take advantage of?

(ii.) Robert, can you provide any information that relates to (d.) 
above? And if there are such cases where static utils are ok in a server 
env when there are significant garbage collection concerns?

(iii.) All, can we consider that there is consistent approach to dealing 
with Equation like math evaluations, whether matrix, statistical or 
numeric. Finding and defining such a consistency will enhance the 
"plug-n-play" capabilities of the library. Providing both a means to 
easily learn, use and combine functionalities across various parts of 
the library.


I think the Functors Design Pattern approaches something similar to the 
Aspect Oriented Design strategy, basically separating the concerns into 
"Data Collections/Objects" and "Functions/Operations" that can be 
evaluate/perform processing on those objects.

Either way, I hope some of us will take a quick over the the package and 
comment according about their opinion. I hope Rodney Waldhoff will feel 
comfortable about stepping back in and discussing some more about his 
approach with us.

The site:
http://jakarta.apache.org/commons/sandbox/functor/

Specifically of interest are the basic interfaces.
http://jakarta.apache.org/commons/sandbox/functor/xref/index.html

-Mark


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


Re: [math][functor] More Design Concerns

Posted by Rodney Waldhoff <rw...@apache.org>.
On Fri, 27 Jun 2003, Rodney Waldhoff wrote:

One of those last points didn't come out quite clear.  I meant to say:

> * When object based functors are created, [if I were you] I'd consider
> implementing the corresponding commons-functor interface, or at least
> leaving room for doing so in the future (for instance, using the same
> method signatures with the same semantics, but not necessarily extending
> or implementing the functor type for now).

- Rod <http://radio.weblogs.com/0122027/>


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


Re: [math][functor] More Design Concerns

Posted by "Mark R. Diggory" <md...@latte.harvard.edu>.
As an alternative, I've been holding off responding to allow others 
voices to be heard. I'm glad, it seems to be working out well and 
generating some interesting discussion. I'll interject some comments 
here so that we understand my intention wasn't to "revamp" the entire 
math package with the Functors approach, but to draw out the very 
discussion about the models that are similar to it in our code.

Please do not worry Phil, I think its wise for us not to rush into any 
major alterations with group consensus one the subject, this is a group 
project, as initial proposer, you have equal voting weight as any of the 
commiters on the project, plus with your strong mathematics background, 
I think your conceptual grasp of the user base of the project helps to 
keep us on track. But, I also think it good to explore other ideas in 
discussion to help keep the project innovative and evolving. Thats my 
primary goal, I think in the end, the tension between traditional and 
alternative ideas will help us to establish a solid design, that as you 
stated meets the requirements you've help to clarify in your last email.

Before interjecting my comments, I'd just like to point out that my 
primary point in starting this discussion is not to have us adopt "one" 
model, and not specifically the "Functors model". But, to foster some 
discussion on these models, similarities in these models, and draw in 
others with experience in these areas. This will help us in later 
decisions we may be making about appropriate implementation and 
refactorings. So in these regards this is turn out to be a very 
successful discussion. (See me interjections below).

Phil Steitz wrote:

>
>> The base idea behind functor is to create large and complex behaviors by
>> composing small and simple (and generally stateless) ones.
>>
>> Part of this is the same as the mathematical notion of the 
>> composition of
>> functions--build a composite function c out of simpler functions. For
>> example:
>>
>>   c(x) :=  f(g(x))
>>
>> or,
>>
>>   c(x,y) := h(f(x),g(y))
>>
>> or,
>>
>>   c(x,y) := f(x) when g(x) is true
>>             f(y) otherwise
>> etc.
>>
>> Another part of this is the composition of arbitrary functions into
>> "templated" algorithms, similar to the Gang-of-Four's "Template Method"
>> pattern, except generally using composition instead of 
>> inheritance/method
>> overloading.  For example, a function like "inject" or "fold":
>>
>>   Object inject(Iterator iter, Object seed, BinaryFunction f) {
>>     while(iter.hasNext()) {
>>       seed = func.evaluate(seed,iter.next());
>>     }
>>     return seed;
>>   }
>>
>> can be used for a very large number of things.  For instance, 
>> ((x<y)?y:x))
>> makes inject into a "max" function, (x+y) makes inject into a "sum"
>> function, ((x*count)+y)/++count) makes inject into an "average" 
>> function,
>> etc.  When combined with the first notion of composition, this becomes a
>> very powerful technique.
>>
>> I think this strategy is quite applicable to mathematics and 
>> commons-math
>> in particular.
>
>
> I agree.  The question is when to bring this kind of machinery in (see 
> comments below).
>
>>
>> Mark also wrote (I think this was Mark anyway):
>>
>>
>>> b.) Which design strategy is of more interest
>>> to the project? Small compact classes used to
>>> complete one specific task, where the programming
>>> is primarily OOD in nature? or Feature rich
>>> interfaces that encapsulate full ranges of
>>> functionality, where programming is primarily
>>> "procedural" in nature?
>>
>>
>>
>> IMO, and as I lurker on commons-math at best, my opinion probably 
>> doesn't
>> and shouldn't carry a lot of weight, the appropriate design strategy 
>> is a
>> functional one, which shares some of the attributes what you describe as
>> OO (but functional is decidedly not OO). 
>
I think however, you have such a strong understanding of this particular 
Functor/Template DP that we would consider you to have somewhat an 
expertise in this area, you opinions valuable in that regard. My usage 
of OO is probably inappropriate in describing Functors.

>>
>
> Can you expand a little on exactly what you mean here, ideally with 
> some specific examples?  Don't limit yourself to what is already 
> implemented in commons-math. 


My point in  (b.) is to discuss what amount to "Facades" approached in 
classes/interfaces like (Store)Univariate and RealMatrix, and the idea 
that there are decisions being made concerning how the "Facades are 
"backed" by various implementation strategies, not to suggest that the 
"Facades" themselves should go away. Right now we have some design 
evolution thats going on in the math.stat package, over the last few 
weeks we've experimented with Abstract  Implementations, Inherited 
Delegation and Static Delegation strategies, currently finding 
satisfaction and dissatisfaction in various aspects of each approach. 
Some cases the inheritance hierarchy got complicated (UnivariateImpl 
extending AbstractStoreUnivariate), some cases the extensibility of the 
implementations becomes a concern (StatUtils being static).   This 
discussion attempts to "draw the problem space" we are encountering here 
and clarify it, Functional approaches are but one means of possibly 
dealing with this problem space.

>
>
>>
>> Phil Steitz wrote:
>>
>>
>>> IMHO, the most important considerations
>>> are 1) how easy the library will be to
>>> navigate and use 2) how maintainable it
>>> will be and 3) how well it will perform
>>> (including resource requirements).
>>
>>
>>
>> I agree with that, and think a functional approach would definitely
>> support the second point (maintainability) and IMO the first (ease of 
>> use)
>> as well. 
>
>
> Can you provide some examples on the ease of use point here?  You 
> don't have to limit them to what exists now in commons-math.  As a 
> mathematician, I might personally be very happy (sometimes) working 
> with function spaces definable by the operations that they support 
> (e.g L-P spaces, groups, rings, fields, etc) but I don't think that 
> non-mathematicians -- or even mathematicians who are lazy programmers 
> -- would like to work in that world.  A concrete example is the 
> "Operable objects" defined in Jade and their use in Jade's matrix 
> class (http://www.dautelle.com/jade/api/com/dautelle/math/Matrix.html).  

> As a user, I would much prefer to work directly with a real matrix 
> (see additional notes below on the special position of reals).  Part 
> of what I am resisting here is the lure of "mathematical domain 
> modelling" -- even from a functional standpoint -- as a primary 
> focus.  I would prefer to keep the focus on the practical applications 
> and bring in the abstractions only as we need them.  I think that it 
> is likely that I am missing your main point, so please (gently) 
> enlighten me. 


I've encountered this issue before when the developers are also the 
users, the developers have stronger assumptions about what the user base 
would like to see in a product. Often I find myself and other developers 
blurring the lines between implementation that enhances development vs. 
implementations/interfaces that will be provided for users . I think we 
need to stay clear on what is for basic "users" and what is for 
developers, this is difficult in a package where the developers are the 
users. I don't believe that we a limited here to functional approaches 
or "direct" access approaches, it is possible that a design could employ 
both.

One example of this would be in retaining the RealMatrix/Impl as facade 
for users while implementing the actual methods in the facade with 
functional approach. The idea then is that the functional approaches can 
be recombined to expand upon the capabilities of the "Facade". For those 
who which to approach that style of programming the functions can also 
be applied as a mathematics "API".

Another Example is in the (Store)Univariate/Impl currently we have two 
or three approaches we are "experimenting" with in an attempt to find 
the correct design. (1.) delegation to Static methods (2.) and 
polymorphic inheritance in AbstractStoreUnivariate. These interfaces of 
Univariate and StoreUnivariate provide easy to use facades for users. 
The implementation behind these Facades could be backed by a number of 
methods, of which, the best is often a matter of opinion.

>
>  The third point (performance) probably isn't helped by a
>
>> functional approach, although it may not be hurt by it either.  I'm 
>> of the
>> "don't do it, yet" philosophy on optimization though.
>
>
> I agree. 

But certain Designs can hinder optimization. For example, currently 
there is an approach in both StatUtils and AbstractStoreUnivariate that 
make multiple passes to calculate variance, using a pass for mean and a 
pass for variance calculation, when the the AbstractStoreUnivariate Kurt 
and skew implementations were originally written, "bean like getter" 
properties (getMean and getVaraince) were used to construct the 
calculation of skew and kurt, this introduces an "extra recalculation" 
of the mean (1 for the getMean, one for getVar). So this gives us an 
example of where the logical reusage of getMean and getVariance to 
implement another method locks us out of an optimized solution. A more 
optimal solution might provide an implementation of a variance 
calculation that can take a "precalculated mean" as a parameter, then 
such "recalculation" is better facilitated. Still this sort of 
optimization could probably be applied to any design scheme. I use skew 
and kurt in this case because I'm most familiar with the code. But I'm 
quite sure this can happen elsewhere.

>
>
>>
>> Phil also wrote:
>>
>>
>>> My opinion here is that a univariate real
>>> function is an object in its own right.
>>> I suppose that it could extend Functor,
>>> but I do not see the point in this and
>>> I would personally not like having to
>>> lose the typing and force use and casting
>>> to Double to implement
>>> Object evaluate(Object obj);
>>
>>
>>
>> A few observations here:
>>
>> 1) A common approach to this sort of problem would be something like:
>>
>> abstract class <Type>UnaryFunction implements UnaryFunction {
>>    final Object evaluate(Object obj) {
>>       return (<Type>)evaluate((<Type>)obj);
>>    }
>>
>>    abstract <Type> evaluate<Type>(<Type> type);
>> }
>>
>> class MyFuction extends <Type>UnaryFunction;
>>
>> etc., but I'll argue that it's the distinction between primitives and
>> their object wrappers that are the concern here.
>
>
> This is certainly part of my problem.  I could get over both of this, 
> however, if I saw big value in having UnivariateRealFunction extend 
> Functor.  Here is more precisely what I am struggling with in the 
> specific case of real-valued functions. When I said that "a 
> real-valued (differentiable) function is an object in its own right" 
> what I really meant was that the fact that its characterization as a 
> (partially) composable mapping does not capture very much -- the most 
> important functional characteristics of a real -> real function make 
> essential use of the fact that its domain and codomain are the real 
> numbers. Things like convolution, integration, differentiation, 
> rootfinding, etc. make no sense at the Functor level. To me, having 
> UnivariateRealFunction extend Functor would be like having Complex 
> extend Group. Sure, you could do it and it makes sense logically, but 
> why introduce the additional layer unless there is a strong practical 
> reason (or anticipated reason) to do so?  Also, just as there are 
> additional natural layers between Complex and Group (Field, Ring) 
> there are also probably additional natural layers between Functor and 
> UnivariateRealFuntion (see more below). I know this is mixing OO and 
> functional ideas, but hopefully you get the point.
>
> Note that this does NOT rule out the applicability of the functor 
> approach for other things down the road.

>
>
>>
>> 2) It may not be necessary to commit to extending or using 
>> commons-functor
>> from the beginning.  Any functional approach is readily adapted to
>> commons-functor.  E.g., given:
>>
>>  interface UnivariateFunction {
>>    Double evaluate(Double x);
>>  }
>>
>> it's not difficult to create a (commons-functor) UnaryFunction adapter:
>>
>>  class Univariate2UnaryFunction implements UnaryFunction {
>>     Univariate2UnaryFunction(UnivariateFunction f) {
>>       this.f = f;
>>     }
>>
>>     Object evaluate(Object obj) {
>>       return f.evaluate((Double)obj);
>>     }
>>
>>     UnivariateFunction f = null;
>>  }
>>
>> which would join the two libraries, but again it's the distinction 
>> between
>> primitives and their object wrappers that are the concern here.
>
>
> Yes. but maybe not a serious concern for some use cases.  This is an 
> interesting idea. I would like to think/discuss some more about the 
> potential uses of this.
>
>>
>> 3) I can imagine primitive versions of the commons-functor interfaces,
>> say:
>>
>> interface DoubleFunction { double evaluate(double); }
>>
>> with either parallel implementations of the functor composers, adapters,
>> and utilities, or with adapters between the two (or both).  (I'm the guy
>> behind most of collections.primitives.* after all.)  But I don't imagine
>> those being part of a version 1 release.
>>
Initially, this was my idea, more so that just adopting the Functor 
approach directly, but to provide for primitive style evaluation, this 
is the chief difference between UnivariateFunction and the Functors package.

>
> Also a very interesting idea.  My intuition is that what will turn out 
> to be useful are not "primitive" versions, but "algebraic" or 
> "mathematical" versions (i.e., versions that use primitives or other 
> mathematical objects as domain, codomain to represent functors with 
> additional algebraic properties).

If I'm getting this correctly, In this statement are you referring 
to"algebraic" or "mathematical" versions similar in Nature to that of 
our "ContinueFraction" class? This further supports the usage of 
Functional programming because, like shown above, an evaluation method 
can be implementation supporting multiple types as necessary, primitive 
or Object.

>
>>
>> In short, and for what it's worth, my suggestion is this:
>>
>> * Where appropriate (and I think it's probably appropriate often),
>> commons-math should follow a functional design, like the one we see in
>> UnivariateFunction.
>

>
> Please point out any additional opportunities/inconsistencies that you 
> can see now or that you see as more gets added to the package. Thanks 
> in advance.
>
>>
>> * This functional approach will probably be based on primitives rather
>> than objects, and hence fully independent of anything in 
>> commons-functor.
>
>
> For now, I agree.  I am intrigued, however, by the idea of 
> "mathematical functors", mostly for use in more strictly mathematical 
> applications than what commons-math is at least initially aiming at.  
> To me, the real distinction is between reals, complex numbers (not yet 
> in the package), matrices, etc and "domain elements", not primitives 
> vs objects.

Great, I'm glad this brought out this as an interesting area to explore. 
Yes, I am not rigid in terms of direct usage/dependency on Functor, more 
exploration may or may not warrant doing this in the future.

>
>>
>> * When object based functors are created, I'd consider implementing the
>> corresponding commons-functor interface, or at least leaving room for
>> doing so in the future (for instance, using the same method signatures
>> with the same semantics, but not necessarily extending or 
>> implementing the
>> functor type for now).
>
>
> I agree.
>
>>
>> * Let's come back to this discussion after a v1 release of both math and
>> functor, and see if we want to start bridging the two APIs more 
>> directly.
>> I think doing so could be very useful, and with just a little bit of
>> forethought, should be fairly easy as well.
>
>
> I agree.  Thanks for the feedback.  Pls help make sure that we don't 
> do anything that will make this harder down the road.
>
> Phil
>
>>
>> - Rod <http://radio.weblogs.com/0122027/>
>

Thank you Rod, Phil and Al, I'm glad we had an opportunity to dig into 
this and explore these ideas. This kinds of discussion can only help us 
in clarifying the directions our implementation can go in.

- Mark

-- 
Mark Diggory
Software Developer
Harvard MIT Data Center
http://www.hmdc.harvard.edu



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


Re: [math][functor] More Design Concerns

Posted by Phil Steitz <ph...@steitz.com>.
> The base idea behind functor is to create large and complex behaviors by
> composing small and simple (and generally stateless) ones.
> 
> Part of this is the same as the mathematical notion of the composition of
> functions--build a composite function c out of simpler functions. For
> example:
> 
>   c(x) :=  f(g(x))
> 
> or,
> 
>   c(x,y) := h(f(x),g(y))
> 
> or,
> 
>   c(x,y) := f(x) when g(x) is true
>             f(y) otherwise
> etc.
> 
> Another part of this is the composition of arbitrary functions into
> "templated" algorithms, similar to the Gang-of-Four's "Template Method"
> pattern, except generally using composition instead of inheritance/method
> overloading.  For example, a function like "inject" or "fold":
> 
>   Object inject(Iterator iter, Object seed, BinaryFunction f) {
>     while(iter.hasNext()) {
>       seed = func.evaluate(seed,iter.next());
>     }
>     return seed;
>   }
> 
> can be used for a very large number of things.  For instance, ((x<y)?y:x))
> makes inject into a "max" function, (x+y) makes inject into a "sum"
> function, ((x*count)+y)/++count) makes inject into an "average" function,
> etc.  When combined with the first notion of composition, this becomes a
> very powerful technique.
> 
> I think this strategy is quite applicable to mathematics and commons-math
> in particular.

I agree.  The question is when to bring this kind of machinery in (see 
comments below).

> 
> Mark also wrote (I think this was Mark anyway):
> 
> 
>>b.) Which design strategy is of more interest
>>to the project? Small compact classes used to
>>complete one specific task, where the programming
>>is primarily OOD in nature? or Feature rich
>>interfaces that encapsulate full ranges of
>>functionality, where programming is primarily
>>"procedural" in nature?
> 
> 
> IMO, and as I lurker on commons-math at best, my opinion probably doesn't
> and shouldn't carry a lot of weight, the appropriate design strategy is a
> functional one, which shares some of the attributes what you describe as
> OO (but functional is decidedly not OO).

Can you expand a little on exactly what you mean here, ideally with some 
specific examples?  Don't limit yourself to what is already implemented 
in commons-math.

> 
> Phil Steitz wrote:
> 
> 
>>IMHO, the most important considerations
>>are 1) how easy the library will be to
>>navigate and use 2) how maintainable it
>>will be and 3) how well it will perform
>>(including resource requirements).
> 
> 
> I agree with that, and think a functional approach would definitely
> support the second point (maintainability) and IMO the first (ease of use)
> as well. 

Can you provide some examples on the ease of use point here?  You don't 
have to limit them to what exists now in commons-math.  As a 
mathematician, I might personally be very happy (sometimes) working with 
function spaces definable by the operations that they support (e.g L-P 
spaces, groups, rings, fields, etc) but I don't think that 
non-mathematicians -- or even mathematicians who are lazy programmers -- 
would like to work in that world.  A concrete example is the "Operable 
objects" defined in Jade and their use in Jade's matrix class 
(http://www.dautelle.com/jade/api/com/dautelle/math/Matrix.html).  As a 
user, I would much prefer to work directly with a real matrix (see 
additional notes below on the special position of reals).  Part of what 
I am resisting here is the lure of "mathematical domain modelling" -- 
even from a functional standpoint -- as a primary focus.  I would prefer 
to keep the focus on the practical applications and bring in the 
abstractions only as we need them.  I think that it is likely that I am 
missing your main point, so please (gently) enlighten me.

  The third point (performance) probably isn't helped by a
> functional approach, although it may not be hurt by it either.  I'm of the
> "don't do it, yet" philosophy on optimization though.

I agree.

> 
> Phil also wrote:
> 
> 
>>My opinion here is that a univariate real
>>function is an object in its own right.
>>I suppose that it could extend Functor,
>>but I do not see the point in this and
>>I would personally not like having to
>>lose the typing and force use and casting
>>to Double to implement
>>Object evaluate(Object obj);
> 
> 
> A few observations here:
> 
> 1) A common approach to this sort of problem would be something like:
> 
> abstract class <Type>UnaryFunction implements UnaryFunction {
>    final Object evaluate(Object obj) {
>       return (<Type>)evaluate((<Type>)obj);
>    }
> 
>    abstract <Type> evaluate<Type>(<Type> type);
> }
> 
> class MyFuction extends <Type>UnaryFunction;
> 
> etc., but I'll argue that it's the distinction between primitives and
> their object wrappers that are the concern here.

This is certainly part of my problem.  I could get over both of this, 
however, if I saw big value in having UnivariateRealFunction extend 
Functor.  Here is more precisely what I am struggling with in the 
specific case of real-valued functions. When I said that "a real-valued 
(differentiable) function is an object in its own right" what I really 
meant was that the fact that its characterization as a (partially) 
composable mapping does not capture very much -- the most important 
functional characteristics of a real -> real function make essential use 
of the fact that its domain and codomain are the real numbers. Things 
like convolution, integration, differentiation, rootfinding, etc. make 
no sense at the Functor level. To me, having UnivariateRealFunction 
extend Functor would be like having Complex extend Group. Sure, you 
could do it and it makes sense logically, but why introduce the 
additional layer unless there is a strong practical reason (or 
anticipated reason) to do so?  Also, just as there are additional 
natural layers between Complex and Group (Field, Ring) there are also 
probably additional natural layers between Functor and 
UnivariateRealFuntion (see more below). I know this is mixing OO and 
functional ideas, but hopefully you get the point.

Note that this does NOT rule out the applicability of the functor 
approach for other things down the road.

> 
> 2) It may not be necessary to commit to extending or using commons-functor
> from the beginning.  Any functional approach is readily adapted to
> commons-functor.  E.g., given:
> 
>  interface UnivariateFunction {
>    Double evaluate(Double x);
>  }
> 
> it's not difficult to create a (commons-functor) UnaryFunction adapter:
> 
>  class Univariate2UnaryFunction implements UnaryFunction {
>     Univariate2UnaryFunction(UnivariateFunction f) {
>       this.f = f;
>     }
> 
>     Object evaluate(Object obj) {
>       return f.evaluate((Double)obj);
>     }
> 
>     UnivariateFunction f = null;
>  }
> 
> which would join the two libraries, but again it's the distinction between
> primitives and their object wrappers that are the concern here.

Yes. but maybe not a serious concern for some use cases.  This is an 
interesting idea. I would like to think/discuss some more about the 
potential uses of this.

> 
> 3) I can imagine primitive versions of the commons-functor interfaces,
> say:
> 
> interface DoubleFunction { double evaluate(double); }
> 
> with either parallel implementations of the functor composers, adapters,
> and utilities, or with adapters between the two (or both).  (I'm the guy
> behind most of collections.primitives.* after all.)  But I don't imagine
> those being part of a version 1 release.
> 

Also a very interesting idea.  My intuition is that what will turn out 
to be useful are not "primitive" versions, but "algebraic" or 
"mathematical" versions (i.e., versions that use primitives or other 
mathematical objects as domain, codomain to represent functors with 
additional algebraic properties).

> 
> In short, and for what it's worth, my suggestion is this:
> 
> * Where appropriate (and I think it's probably appropriate often),
> commons-math should follow a functional design, like the one we see in
> UnivariateFunction.

Please point out any additional opportunities/inconsistencies that you 
can see now or that you see as more gets added to the package. Thanks in 
advance.

> 
> * This functional approach will probably be based on primitives rather
> than objects, and hence fully independent of anything in commons-functor.

For now, I agree.  I am intrigued, however, by the idea of "mathematical 
functors", mostly for use in more strictly mathematical applications 
than what commons-math is at least initially aiming at.  To me, the real 
distinction is between reals, complex numbers (not yet in the package), 
matrices, etc and "domain elements", not primitives vs objects.

> 
> * When object based functors are created, I'd consider implementing the
> corresponding commons-functor interface, or at least leaving room for
> doing so in the future (for instance, using the same method signatures
> with the same semantics, but not necessarily extending or implementing the
> functor type for now).

I agree.
> 
> * Let's come back to this discussion after a v1 release of both math and
> functor, and see if we want to start bridging the two APIs more directly.
> I think doing so could be very useful, and with just a little bit of
> forethought, should be fairly easy as well.

I agree.  Thanks for the feedback.  Pls help make sure that we don't do 
anything that will make this harder down the road.

Phil

> 
> - Rod <http://radio.weblogs.com/0122027/>
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> 




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


Re: [math][functor] More Design Concerns

Posted by Rodney Waldhoff <rw...@apache.org>.
Mark Diggory wrote:

> I'm hoping you might be able to provide
> some viewpoints as to the benefits of
> [the] Functor pattern, and any ideas you
> may have about its application to math?

The base idea behind functor is to create large and complex behaviors by
composing small and simple (and generally stateless) ones.

Part of this is the same as the mathematical notion of the composition of
functions--build a composite function c out of simpler functions. For
example:

  c(x) :=  f(g(x))

or,

  c(x,y) := h(f(x),g(y))

or,

  c(x,y) := f(x) when g(x) is true
            f(y) otherwise
etc.

Another part of this is the composition of arbitrary functions into
"templated" algorithms, similar to the Gang-of-Four's "Template Method"
pattern, except generally using composition instead of inheritance/method
overloading.  For example, a function like "inject" or "fold":

  Object inject(Iterator iter, Object seed, BinaryFunction f) {
    while(iter.hasNext()) {
      seed = func.evaluate(seed,iter.next());
    }
    return seed;
  }

can be used for a very large number of things.  For instance, ((x<y)?y:x))
makes inject into a "max" function, (x+y) makes inject into a "sum"
function, ((x*count)+y)/++count) makes inject into an "average" function,
etc.  When combined with the first notion of composition, this becomes a
very powerful technique.

I think this strategy is quite applicable to mathematics and commons-math
in particular.

Mark also wrote (I think this was Mark anyway):

> b.) Which design strategy is of more interest
> to the project? Small compact classes used to
> complete one specific task, where the programming
> is primarily OOD in nature? or Feature rich
> interfaces that encapsulate full ranges of
> functionality, where programming is primarily
> "procedural" in nature?

IMO, and as I lurker on commons-math at best, my opinion probably doesn't
and shouldn't carry a lot of weight, the appropriate design strategy is a
functional one, which shares some of the attributes what you describe as
OO (but functional is decidedly not OO).

Phil Steitz wrote:

> IMHO, the most important considerations
> are 1) how easy the library will be to
> navigate and use 2) how maintainable it
> will be and 3) how well it will perform
> (including resource requirements).

I agree with that, and think a functional approach would definitely
support the second point (maintainability) and IMO the first (ease of use)
as well.  The third point (performance) probably isn't helped by a
functional approach, although it may not be hurt by it either.  I'm of the
"don't do it, yet" philosophy on optimization though.

Phil also wrote:

> My opinion here is that a univariate real
> function is an object in its own right.
> I suppose that it could extend Functor,
> but I do not see the point in this and
> I would personally not like having to
> lose the typing and force use and casting
> to Double to implement
> Object evaluate(Object obj);

A few observations here:

1) A common approach to this sort of problem would be something like:

abstract class <Type>UnaryFunction implements UnaryFunction {
   final Object evaluate(Object obj) {
      return (<Type>)evaluate((<Type>)obj);
   }

   abstract <Type> evaluate<Type>(<Type> type);
}

class MyFuction extends <Type>UnaryFunction;

etc., but I'll argue that it's the distinction between primitives and
their object wrappers that are the concern here.

2) It may not be necessary to commit to extending or using commons-functor
from the beginning.  Any functional approach is readily adapted to
commons-functor.  E.g., given:

 interface UnivariateFunction {
   Double evaluate(Double x);
 }

it's not difficult to create a (commons-functor) UnaryFunction adapter:

 class Univariate2UnaryFunction implements UnaryFunction {
    Univariate2UnaryFunction(UnivariateFunction f) {
      this.f = f;
    }

    Object evaluate(Object obj) {
      return f.evaluate((Double)obj);
    }

    UnivariateFunction f = null;
 }

which would join the two libraries, but again it's the distinction between
primitives and their object wrappers that are the concern here.

3) I can imagine primitive versions of the commons-functor interfaces,
say:

interface DoubleFunction { double evaluate(double); }

with either parallel implementations of the functor composers, adapters,
and utilities, or with adapters between the two (or both).  (I'm the guy
behind most of collections.primitives.* after all.)  But I don't imagine
those being part of a version 1 release.


In short, and for what it's worth, my suggestion is this:

* Where appropriate (and I think it's probably appropriate often),
commons-math should follow a functional design, like the one we see in
UnivariateFunction.

* This functional approach will probably be based on primitives rather
than objects, and hence fully independent of anything in commons-functor.

* When object based functors are created, I'd consider implementing the
corresponding commons-functor interface, or at least leaving room for
doing so in the future (for instance, using the same method signatures
with the same semantics, but not necessarily extending or implementing the
functor type for now).

* Let's come back to this discussion after a v1 release of both math and
functor, and see if we want to start bridging the two APIs more directly.
I think doing so could be very useful, and with just a little bit of
forethought, should be fairly easy as well.

- Rod <http://radio.weblogs.com/0122027/>


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


Re: [math][functor] More Design Concerns

Posted by David Graham <gr...@yahoo.com>.
> > c.) What is the platform of interest for [math]? Server Side or 
> > Application.

Remember that Jakarta's mission is create *server-side* libraries:
http://jakarta.apache.org/site/mission.html

That doesn't mean that a library couldn't be used in client-side apps but
it does mean that your primary focus should be on server-side concerns. 
Commons Validator is a good example of a library that can be used client
side but was developed primarily for validating html forms in server apps.

David


> 
> We should certainly not have to choose here -- nor should our users. 
> Nothing in the current implementation would create problems in 
> server-side applications -- at least nothing that I can see. If others 
> can see problems, we need to identify and address these specifically. 
> The most important thing to do here is to clearly document interfaces so
> 
> that users know what is stateful, what is not, what is thread-safe, what
> 
> is not, what creates singletons, pools or external storage (nothing so 
> far), etc.
> 
> > 
> > d.) Should static method utilities be avoided at all costs in both 
> > cases? OR are there specific situations were static functions do not 
> > create garbage collection considerations and issues (like, when only 
> > returning primitives).
> 
> I am starting to think that we should avoid static methods, and in fact 
> change StatUtils to require instantiation, but this has nothing to do 
> with garbage collection, since with a stateless collection of static 
> methods, there is no "garbage" to collect -- just a class loaded once 
> per JVM.  As long as there is no state associated with the class, I 
> don't see how classloader problems could really come into play (unless 
> users were relying on classloader priority to load different versions, 
> which is IMHO a bad idea and could apply to any of our classes).  The 
> real issue here is extensibility.  As I think more about the use cases 
> for StatUtils, I am less convinced than I was before that the 
> "convenience" and "efficiency" of not having to create an instance is 
> worth the anxiety about support for extensibility.  Therefore, I would 
> support changing the methods in StatUtils to be non-static.
> 
> > 
> > 
> > (3.) A couple proposals:
> > 
> > (i.) Brent and Pietschmann can you make suggestions/recommendations as
> 
> > to how your "function object" model could be applied to StaticUtil 
> > situations? Are you familiar with the Functors project and is there a 
> > possibility that they should be considered as the basic design
> strategy 
> > or base of implementation for your "Function Object" design? if they
> are 
> > a Commons project as well is there a possible dependency here we could
> 
> > take advantage of?
> 
> My opinion here is that a univariate real function is an object in its 
> own right. I suppose that it could extend Functor, but I do not see the 
> point in this and I would personally not like having to lose the typing 
> and force use and casting to Double to implement
> Object evaluate(Object obj);
> 
> It should also be noted that this is a relatively trivial part of what 
> is really going on in the analysis package (i.e. rootfinding and spline 
> fitting).
> 
> > 
> > (ii.) Robert, can you provide any information that relates to (d.) 
> > above? And if there are such cases where static utils are ok in a
> server 
> > env when there are significant garbage collection concerns?
> > 
> > (iii.) All, can we consider that there is consistent approach to
> dealing 
> > with Equation like math evaluations, whether matrix, statistical or 
> > numeric. Finding and defining such a consistency will enhance the 
> > "plug-n-play" capabilities of the library. Providing both a means to 
> > easily learn, use and combine functionalities across various parts of 
> > the library.
> > 
> > 
> 
> Repeat comments above.  I do not believe that there is a "one size fits 
> all" nor that trying to force everything into a single pattern (which I 
> find hard to imagine) will make things easier.  Remember that many 
> (most?) users will come to commons-math with a specific problem in mind 
> and they will not likely want to invest large amounts of time in 
> learning the "commons-math design philosophy".  If we want to meet the 
> goals in the proposal, we will want to make things as simple and 
> "natural" to users as possible.  Obviously, the 10000 <favorite 
> currency> question is what is most "natural" for each functional area in
> 
> commons-math.
> 
> Another point that we need to keep in mind is that we have a naturally 
> layered structure, which will become even more so over time.  We should 
> be liberal in exposing technical functionality that "most users" will 
> not use and the mathematical orientation of the interfaces will 
> naturally increase as you go deeper into the infrastructure.  For 
> example, Brent did the hard work to derive and implement some special 
> functions that reside in the special package. These were the key to 
> providing the statistical testing/confidence intervals that "more users"
> 
> may use.  "Most users" will not use the special functions directly -- 
> but it is very nice to have them exposed for the mathematical 
> programmers who want to exploit their many uses beyond what we have used
> 
> them internally for. Moving up the layers, "most users" will not use the
> 
> Chi-Square distribution directly (which builds on special); but that is 
> also very nice to have. Continuing up the call stack leading to the 
> stats tests, we come to rootfinding, which more users will use directly 
> and finally to the statistical tests and confidence intervals, which 
> will likely be used directly quite a bit by people with no understanding
> 
> or interest in either rootfinding or special functions.  At each of the 
> layers, a different level of mathematical sophistication is expected and
> 
> different kinds of interfaces are "natural".
> 
> Finally, I think that it is appropriate to in some cases expose what 
> amounts the the "same functionality" via multiple different kinds of 
> interfaces.  For example, to get the mean of a collection of doubles, 
> you can now a) use StatUtils if what you have is an array of doubles and
> 
> all you want is the mean b) instantiate a storage-less Univariate and 
> feed the values in (good for long lists of values that you don't want to
> 
> store in memory) or c) if the numbers whose mean you want happen to be 
> exposed as properties of a collection of beans, instantiate a 
> BeanListUnivariate and use it to get the mean.  I see absolutely nothing
> 
> wrong with this and in fact a lot that is "right" with this -- practical
> 
> use cases drive design and the result is flexibility, convenience and 
> ease of use.
> 
> Phil
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> 


__________________________________
Do you Yahoo!?
SBC Yahoo! DSL - Now only $29.95 per month!
http://sbc.yahoo.com

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


Re: [math][functor] More Design Concerns

Posted by Al Chou <ho...@yahoo.com>.
--- "J.Pietschmann" <j3...@yahoo.de> wrote:
> Al Chou wrote:
> >>>Does staticness preclude extensibility?
> ...
> > I clearly have never studied for a Java certification. <g>  Thanks for the
> > clarification, Phil.
> 
> No difference to C++ or any other language with class methods
> I ever met.

I'm not much of a C/C++ programmer, either (even less so than I am a Java
programmer, actually).  In Ruby it's possible to rename an inherited class
method and then define a new method with the original name, effectively
allowing overriding of class methods.  Maybe it's the dynamic vs. static (no
pun intended) typing that accounts for the difference.


Al

=====
Albert Davidson Chou

    Get answers to Mac questions at http://www.Mac-Mgrs.org/ .

__________________________________
Do you Yahoo!?
SBC Yahoo! DSL - Now only $29.95 per month!
http://sbc.yahoo.com

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


Re: [math][functor] More Design Concerns

Posted by "J.Pietschmann" <j3...@yahoo.de>.
Al Chou wrote:
>>>Does staticness preclude extensibility?
...
> I clearly have never studied for a Java certification. <g>  Thanks for the
> clarification, Phil.

No difference to C++ or any other language with class methods
I ever met.

J.Pietschmann



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


Re: [math][functor] More Design Concerns

Posted by Al Chou <ho...@yahoo.com>.
--- Phil Steitz <ph...@steitz.com> wrote:
> Al Chou wrote:
> > --- Phil Steitz <ph...@steitz.com> wrote:
> > Does staticness preclude extensibility?  I assume final-ity would, but we
> > didn't declare any methods final, AFAIK.
> 
> Strictly speaking, no; but static methods do not support polymorphism 
> and inheritance in the way that instance methods do.  Static methods 
> cannot be overridden in Java.  check out
> http://www.javaworld.com/javaworld/javaqa/2001-05/01-qa-0504-oo.html
> or to get the exact scoop:
>
http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#228745

I clearly have never studied for a Java certification. <g>  Thanks for the
clarification, Phil.


Al

=====
Albert Davidson Chou

    Get answers to Mac questions at http://www.Mac-Mgrs.org/ .

__________________________________
Do you Yahoo!?
SBC Yahoo! DSL - Now only $29.95 per month!
http://sbc.yahoo.com

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


Re: [math][functor] More Design Concerns

Posted by Phil Steitz <ph...@steitz.com>.
Al Chou wrote:
> --- Phil Steitz <ph...@steitz.com> wrote:



> 
> Does staticness preclude extensibility?  I assume final-ity would, but we
> didn't declare any methods final, AFAIK.
> 

Strictly speaking, no; but static methods do not support polymorphism 
and inheritance in the way that instance methods do.  Static methods 
cannot be overridden in Java.  check out
http://www.javaworld.com/javaworld/javaqa/2001-05/01-qa-0504-oo.html
or to get the exact scoop:
http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#228745

Phil


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


Re: [math][functor] More Design Concerns

Posted by Al Chou <ho...@yahoo.com>.
--- Phil Steitz <ph...@steitz.com> wrote:
> > (2) Considerations
> > 
> > a.) Is consistent library design important?Can all these models
> > interace effectively? Are all these different design models required? Is 
> > there a single design model that can span the entire library?
> 
> IMHO, the most important considerations are 1) how easy the library will 
> be to navigate and use 2) how maintainable it will be and 3) how well it 
> will perform (including resource requirements).  For all of these, I 
> think that it is best to look at practical application use cases -- 
> e.g., if someone wants to solve a linear system or estimate a bivariate 
> regression model, how easy will it be for them to do that using 
> commons-math?  How well will the solution perform and scale?  How easy 
> will it be for us to extend it?  Since the library does different kinds 
> of things to satisfy some fundamentally different use cases (e.g. 
> generating a random sample vs modelling algebraic operations on a real 
> matrix) it is natural that multiple design patterns and implementation 
> strategies are used.  Trying to force all commons-math components into a 
> single abstract model is not necessary, IMHO, and would likely make the 
> library harder to use and maintain.

I agree with Phil.  I started to reply to Mark's original message when he
posted it, but I decided to wait, as I felt I was largely basing my opinion on
a possibly inappropriate context (object oriented numerics in C++ discussions
I've followed over the years that largely center on expression templates).  I
do feel pretty strongly that unless consolidating the design of the library
makes it easier for end users to use, I wouldn't make it a priority.  I do
support examining the architecture and design so that we don't release nonsense
or paint ourselves into a corner out of stupidity or laziness, of course.


> > b.) Which design strategy is of more interest to the project? Small 
> > compact classes used to complete one specific task, where the 
> > programming is primarily OOD in nature? or Feature rich interfaces that 
> > encapsulate full ranges of functionality, where programming is primarily 
> > "procedural" in nature?
> 
> Here again, my opinion is that this should be determined by the 
> practical problem being addressed.

Does the intent of commons-math not favor the "small classes" approach
somewhat?


> > d.) Should static method utilities be avoided at all costs in both 
> > cases? OR are there specific situations were static functions do not 
> > create garbage collection considerations and issues (like, when only 
> > returning primitives).
> 
> I am starting to think that we should avoid static methods, and in fact 
> change StatUtils to require instantiation, but this has nothing to do 
> with garbage collection, since with a stateless collection of static 
> methods, there is no "garbage" to collect -- just a class loaded once 
> per JVM.  As long as there is no state associated with the class, I 
> don't see how classloader problems could really come into play (unless 
> users were relying on classloader priority to load different versions, 
> which is IMHO a bad idea and could apply to any of our classes).  The 
> real issue here is extensibility.  As I think more about the use cases 
> for StatUtils, I am less convinced than I was before that the 
> "convenience" and "efficiency" of not having to create an instance is 
> worth the anxiety about support for extensibility.  Therefore, I would 
> support changing the methods in StatUtils to be non-static.

Does staticness preclude extensibility?  I assume final-ity would, but we
didn't declare any methods final, AFAIK.


> > (3.) A couple proposals:
> > 
> > (i.) Brent and Pietschmann can you make suggestions/recommendations as 
> > to how your "function object" model could be applied to StaticUtil 
> > situations? Are you familiar with the Functors project and is there a 
> > possibility that they should be considered as the basic design strategy 
> > or base of implementation for your "Function Object" design? if they are 
> > a Commons project as well is there a possible dependency here we could 
> > take advantage of?
> 
> My opinion here is that a univariate real function is an object in its 
> own right. I suppose that it could extend Functor, but I do not see the 
> point in this and I would personally not like having to lose the typing 
> and force use and casting to Double to implement
> Object evaluate(Object obj);

After briefly looking at Functor's Javadocs, I feel that its interface goes in
a somewhat different direction from that which a mathematical API should. 
While there are commonalities, it seems to me that some of what Functor does is
more easily and naturally expressed using existing mathematical operators
(reminiscent of our discussion of whether, for instance, an isPositive method
would be worth providing in commons-math).  If we were writing a library to do
abstract algebra, we might need interfaces more like Functor's.

 
> It should also be noted that this is a relatively trivial part of what 
> is really going on in the analysis package (i.e. rootfinding and spline 
> fitting).

Good point.  A tangent on terminology:  I would be more comfortable if we made
sure to refer to what we currently have in the library as interpolation.  Curve
fitting is a somewhat different problem from interpolation, most grossly seen
in the fact that a fitted curve need not (and usually will not) pass through
all the input data points, whereas by definition and interpolating curve must.


> Another point that we need to keep in mind is that we have a naturally 
> layered structure, which will become even more so over time.  We should 
> be liberal in exposing technical functionality that "most users" will 
> not use and the mathematical orientation of the interfaces will 
> naturally increase as you go deeper into the infrastructure.  For 
> example, Brent did the hard work to derive and implement some special 
> functions that reside in the special package. These were the key to 
> providing the statistical testing/confidence intervals that "more users" 
> may use.  "Most users" will not use the special functions directly -- 
> but it is very nice to have them exposed for the mathematical 
> programmers who want to exploit their many uses beyond what we have used 
> them internally for. Moving up the layers, "most users" will not use the 
> Chi-Square distribution directly (which builds on special); but that is 
> also very nice to have. Continuing up the call stack leading to the 
> stats tests, we come to rootfinding, which more users will use directly 
> and finally to the statistical tests and confidence intervals, which 
> will likely be used directly quite a bit by people with no understanding 
> or interest in either rootfinding or special functions.  At each of the 
> layers, a different level of mathematical sophistication is expected and 
> different kinds of interfaces are "natural".

Well put.  I feel the same way about the level of sophistication assumed as one
goes deeper into the core of the library.  A pretty unsophisticated user should
be able to get value out of at least some sizable portion of the library, but I
think necessarily we will in the process of building that portion provide
facilities useful to those with more mathematical knowledge (and as you say, we
already have).


> Finally, I think that it is appropriate to in some cases expose what 
> amounts the the "same functionality" via multiple different kinds of 
> interfaces.  For example, to get the mean of a collection of doubles, 
> you can now a) use StatUtils if what you have is an array of doubles and 
> all you want is the mean b) instantiate a storage-less Univariate and 
> feed the values in (good for long lists of values that you don't want to 
> store in memory) or c) if the numbers whose mean you want happen to be 
> exposed as properties of a collection of beans, instantiate a 
> BeanListUnivariate and use it to get the mean.  I see absolutely nothing 
> wrong with this and in fact a lot that is "right" with this -- practical 
> use cases drive design and the result is flexibility, convenience and 
> ease of use.

Yes, I agree what we have in this example is a good case of providing a very
short distance between "what I have" (e.g., a double[]) and "what I want" (the
mean of the values therein), while making a good effort to avoid unnecessary
duplication in the underlying implementation (we seem to talk about that a lot,
anyway <g>).



Al

=====
Albert Davidson Chou

    Get answers to Mac questions at http://www.Mac-Mgrs.org/ .

__________________________________
Do you Yahoo!?
SBC Yahoo! DSL - Now only $29.95 per month!
http://sbc.yahoo.com

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


Re: [math][functor] More Design Concerns

Posted by Phil Steitz <ph...@steitz.com>.

> 
> (2) Considerations
> 
> a.) Is consistent library design important?Can all these models
> interace effectively? Are all these different design models required? Is 
> there a single design model that can span the entire library?

IMHO, the most important considerations are 1) how easy the library will 
be to navigate and use 2) how maintainable it will be and 3) how well it 
will perform (including resource requirements).  For all of these, I 
think that it is best to look at practical application use cases -- 
e.g., if someone wants to solve a linear system or estimate a bivariate 
regression model, how easy will it be for them to do that using 
commons-math?  How well will the solution perform and scale?  How easy 
will it be for us to extend it?  Since the library does different kinds 
of things to satisfy some fundamentally different use cases (e.g. 
generating a random sample vs modelling algebraic operations on a real 
matrix) it is natural that multiple design patterns and implementation 
strategies are used.  Trying to force all commons-math components into a 
single abstract model is not necessary, IMHO, and would likely make the 
library harder to use and maintain.

> 
> b.) Which design strategy is of more interest to the project? Small 
> compact classes used to complete one specific task, where the 
> programming is primarily OOD in nature? or Feature rich interfaces that 
> encapsulate full ranges of functionality, where programming is primarily 
> "procedural" in nature?

Here again, my opinion is that this should be determined by the 
practical problem being addressed.

> 
> c.) What is the platform of interest for [math]? Server Side or 
> Application.

We should certainly not have to choose here -- nor should our users. 
Nothing in the current implementation would create problems in 
server-side applications -- at least nothing that I can see. If others 
can see problems, we need to identify and address these specifically. 
The most important thing to do here is to clearly document interfaces so 
that users know what is stateful, what is not, what is thread-safe, what 
is not, what creates singletons, pools or external storage (nothing so 
far), etc.

> 
> d.) Should static method utilities be avoided at all costs in both 
> cases? OR are there specific situations were static functions do not 
> create garbage collection considerations and issues (like, when only 
> returning primitives).

I am starting to think that we should avoid static methods, and in fact 
change StatUtils to require instantiation, but this has nothing to do 
with garbage collection, since with a stateless collection of static 
methods, there is no "garbage" to collect -- just a class loaded once 
per JVM.  As long as there is no state associated with the class, I 
don't see how classloader problems could really come into play (unless 
users were relying on classloader priority to load different versions, 
which is IMHO a bad idea and could apply to any of our classes).  The 
real issue here is extensibility.  As I think more about the use cases 
for StatUtils, I am less convinced than I was before that the 
"convenience" and "efficiency" of not having to create an instance is 
worth the anxiety about support for extensibility.  Therefore, I would 
support changing the methods in StatUtils to be non-static.

> 
> 
> (3.) A couple proposals:
> 
> (i.) Brent and Pietschmann can you make suggestions/recommendations as 
> to how your "function object" model could be applied to StaticUtil 
> situations? Are you familiar with the Functors project and is there a 
> possibility that they should be considered as the basic design strategy 
> or base of implementation for your "Function Object" design? if they are 
> a Commons project as well is there a possible dependency here we could 
> take advantage of?

My opinion here is that a univariate real function is an object in its 
own right. I suppose that it could extend Functor, but I do not see the 
point in this and I would personally not like having to lose the typing 
and force use and casting to Double to implement
Object evaluate(Object obj);

It should also be noted that this is a relatively trivial part of what 
is really going on in the analysis package (i.e. rootfinding and spline 
fitting).

> 
> (ii.) Robert, can you provide any information that relates to (d.) 
> above? And if there are such cases where static utils are ok in a server 
> env when there are significant garbage collection concerns?
> 
> (iii.) All, can we consider that there is consistent approach to dealing 
> with Equation like math evaluations, whether matrix, statistical or 
> numeric. Finding and defining such a consistency will enhance the 
> "plug-n-play" capabilities of the library. Providing both a means to 
> easily learn, use and combine functionalities across various parts of 
> the library.
> 
> 

Repeat comments above.  I do not believe that there is a "one size fits 
all" nor that trying to force everything into a single pattern (which I 
find hard to imagine) will make things easier.  Remember that many 
(most?) users will come to commons-math with a specific problem in mind 
and they will not likely want to invest large amounts of time in 
learning the "commons-math design philosophy".  If we want to meet the 
goals in the proposal, we will want to make things as simple and 
"natural" to users as possible.  Obviously, the 10000 <favorite 
currency> question is what is most "natural" for each functional area in 
commons-math.

Another point that we need to keep in mind is that we have a naturally 
layered structure, which will become even more so over time.  We should 
be liberal in exposing technical functionality that "most users" will 
not use and the mathematical orientation of the interfaces will 
naturally increase as you go deeper into the infrastructure.  For 
example, Brent did the hard work to derive and implement some special 
functions that reside in the special package. These were the key to 
providing the statistical testing/confidence intervals that "more users" 
may use.  "Most users" will not use the special functions directly -- 
but it is very nice to have them exposed for the mathematical 
programmers who want to exploit their many uses beyond what we have used 
them internally for. Moving up the layers, "most users" will not use the 
Chi-Square distribution directly (which builds on special); but that is 
also very nice to have. Continuing up the call stack leading to the 
stats tests, we come to rootfinding, which more users will use directly 
and finally to the statistical tests and confidence intervals, which 
will likely be used directly quite a bit by people with no understanding 
or interest in either rootfinding or special functions.  At each of the 
layers, a different level of mathematical sophistication is expected and 
different kinds of interfaces are "natural".

Finally, I think that it is appropriate to in some cases expose what 
amounts the the "same functionality" via multiple different kinds of 
interfaces.  For example, to get the mean of a collection of doubles, 
you can now a) use StatUtils if what you have is an array of doubles and 
all you want is the mean b) instantiate a storage-less Univariate and 
feed the values in (good for long lists of values that you don't want to 
store in memory) or c) if the numbers whose mean you want happen to be 
exposed as properties of a collection of beans, instantiate a 
BeanListUnivariate and use it to get the mean.  I see absolutely nothing 
wrong with this and in fact a lot that is "right" with this -- practical 
use cases drive design and the result is flexibility, convenience and 
ease of use.

Phil



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


Re: [math][functor] More Design Concerns

Posted by "Mark R. Diggory" <md...@latte.harvard.edu>.
Rodney Waldhoff wrote:

>On Tue, 24 Jun 2003, Mark R. Diggory wrote:
>
>  
>
>>Either way, I hope some of us will take a quick over the the package and
>>comment according about their opinion. I hope Rodney Waldhoff will feel
>>comfortable about stepping back in and discussing some more about his
>>approach with us.
>>    
>>
>
>For the record, I did notice this statement directed at me.  I haven't had
>a chance to look at math in any detail yet, nor have I been following the
>[math] threads closely, but I'll see if I can find the time to poke around
>in the code.  It might be a little easier to respond if there were a
>specific question here (or maybe there is and I'm just being dim).  I'd be
>pleased if others were to weigh in with an opinion or two here as well.
>
>- Rod <http://radio.weblogs.com/0122027/>
>

Hi Rod,

A short while ago, a discussion popped up in [math] having to do with 
MathUtils/StatUtils being static classes (in our initial attempt to keep 
with the theme established in java.util.Math/StrictMath). There was 
considerable debate for both keeping them static vs something along the 
lines of Singleton Objects. It is also the case that we have a number of 
different Object Models/Design patterns rolling around in [math], one of 
them approaches something similar to "Functors", the others approach 
more traditional encapsulations of both data and methods. I'm beginning 
to think that it would be logical to explore ideas about standardizing 
some of the Design Patterns for [math]. I think this would be expecially 
important now, before we reach a release, because after that point our 
ability to adapt dramatic refactorings is limited by the existence of a 
userbase and established interfaces.

I'm hoping you might be able to provide some viewpoints as to the 
benefits of your Functor pattern, and any ideas you may have about its 
application to math? I started to explore some refactorings that adapted 
the math.stat.Univariate/TestStatistic statistics library into a Functor 
Design Pattern, but didn't want to get too deep into it before others 
weighed in with their opinions on the idea. So, I suspect your correct 
about wanting to hear others opinions from the math group concerning 
such ideas (I do to), if you would wish to wait for others frmalize 
their opinions before exploring this further, I understand.

-Mark

-- 
Mark Diggory
Software Developer
Harvard MIT Data Center
http://www.hmdc.harvard.edu



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


Re: [math][functor] More Design Concerns

Posted by Rodney Waldhoff <rw...@apache.org>.
On Tue, 24 Jun 2003, Mark R. Diggory wrote:

> Either way, I hope some of us will take a quick over the the package and
> comment according about their opinion. I hope Rodney Waldhoff will feel
> comfortable about stepping back in and discussing some more about his
> approach with us.

For the record, I did notice this statement directed at me.  I haven't had
a chance to look at math in any detail yet, nor have I been following the
[math] threads closely, but I'll see if I can find the time to poke around
in the code.  It might be a little easier to respond if there were a
specific question here (or maybe there is and I'm just being dim).  I'd be
pleased if others were to weigh in with an opinion or two here as well.

- Rod <http://radio.weblogs.com/0122027/>

> The site:
> http://jakarta.apache.org/commons/sandbox/functor/
>
> Specifically of interest are the basic interfaces.
> http://jakarta.apache.org/commons/sandbox/functor/xref/index.html
>
> -Mark
>

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


Re: [math][functor] More Design Concerns

Posted by "Mark R. Diggory" <md...@latte.harvard.edu>.
J.Pietschmann wrote:

> 5 Static functions for calculating higher moments for arrays are unwise,
>   because the array is repeatedly scanned if several moments are to be
>   computed. This should be encapsulated in an object which can hold 
> already
>   computed results across invocations of different calculating routines.

The impementations are based on approaches which provide greater 
accuracy and reduced roundoff error (see papers referenced in javadoc),

You are correct however, there is an extra iteration over the array 
between the calc of the mean and the calc of variance. I can rectify 
this easily in the higher moments (which were copied straight out of the 
AbstractStoreUnivariate implementation.. But the two pass approach for 
variance and higher moments is on purpose. These can be corrected with 
out the drastic measer of completely removing them.

-Mark

-- 
Mark Diggory
Software Developer
Harvard MIT Data Center
http://www.hmdc.harvard.edu



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


Re: [math][functor] More Design Concerns

Posted by "J.Pietschmann" <j3...@yahoo.de>.
Phil Steitz wrote:
> I agree. My preference would be to eliminate the original 
> RootFinding.java and refactor the distribution inversion methods to use 
> the new framework.  Before taking that step, however, I would like to 
> hear Brent's opinion on what might be improved in the new framework.

I've taken a look at this and the other problems.
If nobody objects until wendesday or so, I'll ask
for karma and hopefully start work on it on weekend.

Is this ok?

J.Pietschmann



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


Re: [math][functor] More Design Concerns

Posted by "J.Pietschmann" <j3...@yahoo.de>.
Phil Steitz wrote:
>> 3 Both MathException and ConvergenceException don't compile on Java 1.3
>>   and nobody noticed. This is ugly:
> Ranks inserted (IMHO, of course)

Agreed with rankings. However, I think in the long term either
the recursive exception should be factored out of [lang] into
a separate package for better reuse, or merge [math] with [lang]
into a somewhat bigger package resembling a extension to the
whole java.lang+java.util+java.text combo.

> Part of the reason for 
> packing it all into RealMatrix was the need to keep the LU decomposition 
> handy to avoid having to recompute it.

I'd think so. Nevertheless, better modularization allows for
people which can afford to dive into the more complex network
of interfaces to more extensively customize the solving algorithm
and, more important, discard the LU-data and other auxillary stuff
quickly after it is no longer needed.
I'd like to have both: small components for experts and convenient
interfaces to allow unsophisticated users to have a quick shot at
solving their problem.

> I have to confess, however, that I have 
> never liked this.add(that) syntax

Mee to: it runs counter to how the equations are printed in books for
hundreds of years. From this point of view its a pity Java doesn't
have user defined operators and operator overloading (this doesn't mean
I'd like to have this in Java).

> I am interested in what 
> others think about this -- especially others who might actually use real 
> matrices in their programs.

Whoever uses Java for extensive numerical calculations is soon tempted
to abandon it and go either to FORTRAN (maximal performance and the
most mature libraries) or C++ (near FORTRAN performance and much improved
code maintainability). I see [math] mainly useful for descriptive and
partly for analytical statistics, because this functionality is actually
used in the business/web service environment where Java is a major player.

For the same reason I support the idea of adding financial math
functionality (Black-Scholes anyone? :-).

Interpolation as it is currently implemented is only of limited use in
this context, I guess it would be mostly used to draw a graph of the
function (suggestions for adding Java2D integration welcome). There's
obviously overlap with graphing/diagram packages like JFreeChart, but
we don't have any such package at Apache anyway.

Solving linear equation systems may have some use in this environment
too, but I can't imagine that general matrix calculations are used on
a regular basis. Nobody is going to solve economical networks or
calculating magnetical fields in a web application.
Well, there is bayesian and vector based text classification, as in
statistical spam filtering, of course.

Anyone out there willing team up to add graph and diagram layout to
j-c-s-graph? The book is Battista et al: Graph Drawing, ISBN 0133016153.

> Note that to me, solve() is conceptually no different from add

But it is. add() represents an operator, solve() represents a complex
algorithm, depending on more data like accuracy concerns than add().

>> 6 Factorials and binominal coefficients
> Interesting perspective.  The uses that I had in mind were for discrete 
> probability distributions

Ah, forgot about these.

J.Pietschmann


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


Re: [math][functor] More Design Concerns

Posted by "J.Pietschmann" <j3...@yahoo.de>.
Brent Worden wrote:
> The only issues I have are with the UnivariateRealSolverFactory class.  I
> feel there should be a separation of the factory method and the solve
> methods.  I don't think the solve method belong on a factory.  They are more
> appropriately placed (do I dare say) in a SolverUtils utility type class.
> 
> Also, for the factory to provide its intended flexibility, I would
> reimplement it using the abstract factory design pattern.  This allows the
> factory to be swapped in and out at the user's leisure.

I'll take this into account when I'm rewriting the code.

> That makes sense.  I would suggest moving ConvergenceException out of
> org.apache.commons.math.analysis because I think we'll eventually have a
> cyclical package dependency with org.apache.commons.math.util as
> ContinuedFraction depends on ConvergenceException.

Well, cyclic dependencies are not the same headache in Java as in
other programming environments, but it is usually a good idea to
place basic stuff used across several packages into an own package.

J.Pietschmann




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


RE: [math][functor] More Design Concerns

Posted by Brent Worden <br...@worden.org>.
Sorry for my non-response on any part of this thread.  I've been away on
vacation.

> -----Original Message-----
> From: Phil Steitz [mailto:phil@steitz.com]
> Sent: Friday, June 27, 2003 7:20 PM
> To: Jakarta Commons Developers List
> Subject: Re: [math][functor] More Design Concerns
>
>
> J.Pietschmann wrote:
> > Mark R. Diggory wrote:
> >
>
> >
> > Further comments:
> > 1 Now there are two root finding frameworks in place. I think
> this should
> >   be unified.
>
> I agree. My preference would be to eliminate the original
> RootFinding.java and refactor the distribution inversion methods to use
> the new framework.  Before taking that step, however, I would like to
> hear Brent's opinion on what might be improved in the new framework.

The only issues I have are with the UnivariateRealSolverFactory class.  I
feel there should be a separation of the factory method and the solve
methods.  I don't think the solve method belong on a factory.  They are more
appropriately placed (do I dare say) in a SolverUtils utility type class.

Also, for the factory to provide its intended flexibility, I would
reimplement it using the abstract factory design pattern.  This allows the
factory to be swapped in and out at the user's leisure.

As it stands the factory can only create one product even though there are
several products that could be created.  If a user wants/needs to create a
specific solver, they must circumvent the factory and use the constructor.
This defeats the whole purpose of the factory which is to control product
creation.  I would suggest adding factory methods that enable the creation
of the other products.

>
> > 2 Either derive ConvergenceException from MathException and use it in
> >   BrentSolver and SecantSolver too for indicating convergence problems,
> >   or replace it in or somewhere near Gamma.java with a MathException.
>
> I agree.  My vote would be to leave MathException in math and derive
> ConvergenceException in analysis from it.
>

That makes sense.  I would suggest moving ConvergenceException out of
org.apache.commons.math.analysis because I think we'll eventually have a
cyclical package dependency with org.apache.commons.math.util as
ContinuedFraction depends on ConvergenceException.

>
> > 6 Factorials and binominal coefficients are classical classroom
> examples,
> >   but I never saw them in any real world implementation of a numerical
> >   algorithm. Well, with the possible exception of number theory related
> >   stuff. In fact, encountering these is usually an indication that the
> >   algorithm could be sped up by at least an order of magnitude.
>
> Interesting perspective.  The uses that I had in mind were for discrete
> probability distributions (and yes, maybe some number-theoretic or
> purely combinatorial stuff).  I have from time to time needed to compute
> binomial coefficients and/or probabilities in testing or simulation
> applications. Now that we have the Gamma function, binomial
> probablilities don't really need binomial coefficients.  If others agree
> that these will have limited practical application, I would be OK with
> dropping them.

1) "limited practical application" implies some practical application.
2) They are already coded, tested, and working.
Therefore, I would suggest leaving them in.

Brent Worden
http://www.brent.worden.org


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


Re: [math][functor] More Design Concerns

Posted by Phil Steitz <ph...@steitz.com>.
J.Pietschmann wrote:
> Mark R. Diggory wrote:
> 

> 
> Further comments:
> 1 Now there are two root finding frameworks in place. I think this should
>   be unified.

I agree. My preference would be to eliminate the original 
RootFinding.java and refactor the distribution inversion methods to use 
the new framework.  Before taking that step, however, I would like to 
hear Brent's opinion on what might be improved in the new framework.

> 2 Either derive ConvergenceException from MathException and use it in
>   BrentSolver and SecantSolver too for indicating convergence problems,
>   or replace it in or somewhere near Gamma.java with a MathException.

I agree.  My vote would be to leave MathException in math and derive 
ConvergenceException in analysis from it.

> 3 Both MathException and ConvergenceException don't compile on Java 1.3
>   and nobody noticed. This is ugly:

Ouch!  need to fix this.

Ranks inserted (IMHO, of course)

>   - implement the recursive exception mechanisms in MathException, as
>     everybody else does, or

#2

>   - get such an implementation from elsewhere

#1 Look at the nested package in lang.

>    (commons-recursive-exception? :-),
>   - conditionally compile something, probably making a JDK 1.4 compiled
>     commons-math.jar incompatible with JRE 1.3

#4 boo hiss -- violates stated commitment

>   - remove the constructors with recursive throwables, as they aren't
>     yet used anyway.

#3.

> 4 LU composition and equation system solvers should be put in a separate
>   class, similar to root finders. RealMatrix should only hold data and
>   provide arithmetic. It may be necessary to have an additional object
>   for holding the LU-data as a result of the decomposition algorithm.
>   a static function can provide a simple interface to solving equation
>   systems using default algorithms, the same way it is done in the root
>   solving framework.

I could go along with the bean vs. operations separation, but I would 
want to do the whole thing -- not just separate out solve and LU decomp. 
That is what I did in the still not submitted Complex class.  If others 
agree, I can refactor to leave only properties in the matrix class -- 
i.e., encapsulate all matrix operations, including add, multiply, etc 
and certainly solve in a MatrixUtils class.  Part of the reason for 
packing it all into RealMatrix was the need to keep the LU decomposition 
handy to avoid having to recompute it.  I will think about ways to do 
this without having to either a) keep recomputing the LU decomp b) copy 
too much data or c) expose too much.  Suggestions are welcome.  The 
other part of the reason that I left everything in RealMatrix was 
"navigability" or "convenience".  The current interface is really very 
simple and I thought it would be easy for users to quickly find what 
they were looking for if all supported real matrix operations were 
encapsulated in RealMatrix.  I have to confess, however, that I have 
never liked this.add(that) syntax -- regardless of how "functionalist" 
or "non-OO" that perspective may brand me.  I am interested in what 
others think about this -- especially others who might actually use real 
matrices in their programs.

Note that to me, solve() is conceptually no different from add -- both 
are matrix -> matrix operations and neither can meaningfully be 
construed as a matrix property.

> 6 Factorials and binominal coefficients are classical classroom examples,
>   but I never saw them in any real world implementation of a numerical
>   algorithm. Well, with the possible exception of number theory related
>   stuff. In fact, encountering these is usually an indication that the
>   algorithm could be sped up by at least an order of magnitude.

Interesting perspective.  The uses that I had in mind were for discrete 
probability distributions (and yes, maybe some number-theoretic or 
purely combinatorial stuff).  I have from time to time needed to compute 
binomial coefficients and/or probabilities in testing or simulation 
applications. Now that we have the Gamma function, binomial 
probablilities don't really need binomial coefficients.  If others agree 
that these will have limited practical application, I would be OK with 
dropping them.

Thanks for the feedback.

Phil
> 
> J.Pietschmann
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> 




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


Re: [math][functor] More Design Concerns

Posted by "J.Pietschmann" <j3...@yahoo.de>.
Mark R. Diggory wrote:
> a.) Is consistent library design important?

What's consistency?
Mathematical functions, one of the most fundamental stuff
in mathematics, are at least in syntax incompatible with Java
OOP. Offering a syntax which is close to a model already used
for several hundred years should be a consideration. Of course,
Java source can't offer overloaded operators and so on, so there
are limits.

> d.) Should static method utilities be avoided at all costs in both 
> cases?

No. There are legitimate use cases:
1. Factory methods. No argument.
2. If the functionality does not need data persisting the function call,
  there is clearly a "best" implementation (no need to override), no
  configuration data (as opposed to the obvious parameters), and no clear
  "object" (or rather, a class) to attach the the functionality, a static
  method can be the most intuitive design. The Java library has examples,
  like j.u.Arrays.* and of course Math.*.
Candidates not in the Java library: max(x,y), max(array)
Grey zone: calculate gamma(x) (consider accuracy settings configurable)
Out: matrix inversion (no single "best" algorithm)

> (i.)  Are you familiar with the Functors project and is there a 
> possibility that they should be considered as the basic design strategy 
> or base of implementation for your "Function Object" design?

No. But I consider the UnivariateRealFunction as an avoidable
artefact if Java only had function pointers. However, in this
special case saving data while computing the function value in
order to be used in a follow-up computation of the derivative at
the same argument would be enough of a reason to introduce the
concept anyway. FORTRAN programs use global data for this purpose,
but then FORTRAN doesn't have threads and more possibilities for
the compiler to watch which part of the code overwrites which data.

> And if there are such cases where static utils are ok in a server 
> env when there are significant garbage collection concerns?

I don't think static functions can cause any memory or GC related
problem. If static functions pose a problem, then its typically
an MT related problem, either unsync'd methods (duh!) or blocked
threads. If they don't use any static data, such problems shouldn't
occur.


Further comments:
1 Now there are two root finding frameworks in place. I think this should
   be unified.
2 Either derive ConvergenceException from MathException and use it in
   BrentSolver and SecantSolver too for indicating convergence problems,
   or replace it in or somewhere near Gamma.java with a MathException.
3 Both MathException and ConvergenceException don't compile on Java 1.3
   and nobody noticed. This is ugly: we could
   - implement the recursive exception mechanisms in MathException, as
     everybody else does, or
   - get such an implementation from elsewhere
    (commons-recursive-exception? :-),
   - conditionally compile something, probably making a JDK 1.4 compiled
     commons-math.jar incompatible with JRE 1.3
   - remove the constructors with recursive throwables, as they aren't
     yet used anyway.
4 LU composition and equation system solvers should be put in a separate
   class, similar to root finders. RealMatrix should only hold data and
   provide arithmetic. It may be necessary to have an additional object
   for holding the LU-data as a result of the decomposition algorithm.
   a static function can provide a simple interface to solving equation
   systems using default algorithms, the same way it is done in the root
   solving framework.
5 Static functions for calculating higher moments for arrays are unwise,
   because the array is repeatedly scanned if several moments are to be
   computed. This should be encapsulated in an object which can hold already
   computed results across invocations of different calculating routines.
6 Factorials and binominal coefficients are classical classroom examples,
   but I never saw them in any real world implementation of a numerical
   algorithm. Well, with the possible exception of number theory related
   stuff. In fact, encountering these is usually an indication that the
   algorithm could be sped up by at least an order of magnitude.

J.Pietschmann



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