www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - MathExp: KISS or All-Out?

reply dsimcha <dsimcha yahoo.com> writes:
I'm working on some mathy modules that I'd like to eventually contribute to
Phobos, or, if they're too niche, to a standalone lib.  One that I've alluded
to here in the past few days is MathExp.  Basically what it does is
parse/interpret/evaluate/manipulate mathematical expressions at runtime.
Here's a summary of what I've got working so far:

MathExp numerator = mathExp("x^2 * cos(x)", "x");
MathExp denominator = mathExp("exp(-x)", "x");
MathExp ratio = numerator / denominator;

// Print the result of
// (x^2 * cos(x)) / (exp(-x)) evaluated at x = 5.
writeln(ratio(5));

// Compute a derivative symbolically.
MathExp derivDenominator = denominator.derivative("x");

I'm trying to figure out which one makes more sense in the grand scheme of
things.  MathExp might be best kept very simple and stupid and pretty much
left as is, possibly even with the symbolic differentiation capabilities
removed (though these contribute surprisingly little to the weight of the
code; I wrote most of them in one evening just to see if I could).  It would
be easy to use, understand and debug, but be very stupid and have virtually no
semantic understanding of the expressions it's manipulating.  It wouldn't even
be able to simplify, for example, (1 + x + 1) -> (x + 2).

On the other hand, I could take this to the nth degree and add things like
decent printing capabilities (right now, my toString() method is a huge
kludge, is intended for debugging purposes, and puts in tons of unnecessary
parentheses).  I could figure out how to add some semantic analysis to
simplify expressions, maybe symbolic equation solving in some simple cases,
etc.  The downside to this is that I would be reinventing the computer algebra
system in D, which might be a bit too much for a small hobby project that's
intended as a Phobos module.  I'd likely make the code an order of magnitude
more complicated than it is now and might end up reinventing a square wheel or
writing some really buggy code.

If the goal here is to build a Phobos module or standalone plain old library,
do you think the KISS approach or the full-fledged approach is more useful to
the D community?
Oct 14 2009
next sibling parent reply Chad J <chadjoan __spam.is.bad__gmail.com> writes:
I'm reminded of how annoying it is when there are different libraries
for a language that all define their mathematical types differently and
in incompatible ways (all of the Vec2D, Vec3D, etc ever).  Also
aggravating is when there is one canonical type that everyone uses, but
it is a poor choice (char* in C for strings).

It seems like you're in the position to define some canonical CAS types
for D.

So I'd say don't sweat the depth of library procedures too much, but
please get the type definitions (and anything else fundamental) right.
That way libraries that rely on CAS capabilities can talk to each other
without ugliness happening.  In depth procedures to operate on these
types can be implemented in 3rd party libs as necessary, since I can
imagine this stuff getting very very deep, way more so than is
appropriate for phobos.

Just my opinion.  I'm not a CAS pro or anything.
Oct 14 2009
next sibling parent reply language_fan <foo bar.com.invalid> writes:
Thu, 15 Oct 2009 02:04:09 -0400, Chad J thusly wrote:

 I'm reminded of how annoying it is when there are different libraries
 for a language that all define their mathematical types differently and
 in incompatible ways (all of the Vec2D, Vec3D, etc ever).  Also
 aggravating is when there is one canonical type that everyone uses, but
 it is a poor choice (char* in C for strings).
 

Sometimes it feels like Vec3 must be the most reimplemented wheel on the world.
Oct 15 2009
parent reply gzp <galap freemail.hu> writes:
language_fan írta:
 Thu, 15 Oct 2009 02:04:09 -0400, Chad J thusly wrote:
 
 I'm reminded of how annoying it is when there are different libraries
 for a language that all define their mathematical types differently and
 in incompatible ways (all of the Vec2D, Vec3D, etc ever).  Also
 aggravating is when there is one canonical type that everyone uses, but
 it is a poor choice (char* in C for strings).

Sometimes it feels like Vec3 must be the most reimplemented wheel on the world.

Yes, i've also started to implement my own matrix/vector library, though could not get too far yet, as I have to learn D meanwhile. I've checked some existing ones (ex. Lyla, and some other on dsource - don't remember the name, sorry), but my main problem was that, - the implementation could not be altered as desired (ex. I need a sparse matrix, where the matrix elements grouped using a quad-tree ) - didn't like the coding style ( ex. "_" in function names). In some previous post there was some discussion about this and from my experiences even though we found libraries that has all the capability we required, we did not used them. Sometimes we didn't used our colleagues (good, well-planned) codes either b/c the style differed so much (ex capital letters, "_", m prefix for members etc.) So if a language can enforce a style (at least giving some warnings - and turning on treat warnings as errors :) ), that really helps to reuse codes. Well, it's another topic... - too general where it is not required for me, but could not extend where it is needed for me - seemed to be hard to implement a "general" n-d geometry lib based on them(ex 2d/3d/nd ray, sphere, plane, etc, simplicals, space partitioning in n-d etc.) So it'd be really great to create a "new" d mathematical library, that is developed and discussed by a group. Ok, I know there are wrappers for BLAS and other C libraries, but I'd like to see a library written entirely in D.
Oct 16 2009
parent Fawzi Mohamed <fmohamed mac.com> writes:
On 2009-10-16 11:13:59 +0200, gzp <galap freemail.hu> said:

 language_fan írta:
 Thu, 15 Oct 2009 02:04:09 -0400, Chad J thusly wrote:
 
 I'm reminded of how annoying it is when there are different libraries
 for a language that all define their mathematical types differently and
 in incompatible ways (all of the Vec2D, Vec3D, etc ever).  Also
 aggravating is when there is one canonical type that everyone uses, but
 it is a poor choice (char* in C for strings).
 

Sometimes it feels like Vec3 must be the most reimplemented wheel on the world.

Yes, i've also started to implement my own matrix/vector library, though could not get too far yet, as I have to learn D meanwhile. I've checked some existing ones (ex. Lyla, and some other on dsource - don't remember the name, sorry), but my main problem was that, - the implementation could not be altered as desired (ex. I need a sparse matrix, where the matrix elements grouped using a quad-tree ) - didn't like the coding style ( ex. "_" in function names). In some previous post there was some discussion about this and from my experiences even though we found libraries that has all the capability we required, we did not used them. Sometimes we didn't used our colleagues (good, well-planned) codes either b/c the style differed so much (ex capital letters, "_", m prefix for members etc.) So if a language can enforce a style (at least giving some warnings - and turning on treat warnings as errors :) ), that really helps to reuse codes. Well, it's another topic... - too general where it is not required for me, but could not extend where it is needed for me - seemed to be hard to implement a "general" n-d geometry lib based on them(ex 2d/3d/nd ray, sphere, plane, etc, simplicals, space partitioning in n-d etc.) So it'd be really great to create a "new" d mathematical library, that is developed and discussed by a group. Ok, I know there are wrappers for BLAS and other C libraries, but I'd like to see a library written entirely in D.

I think you are greatly underestimating the effort of making "just a library for matrixes and vectors" I think that there are at least 3 areas that have quite different tradeoffs: * small vectors/matrixes, fixed size * large dense vector/matrixes * sparse matrixes/vectors I did just dense matrixes, in blip, and blas is used if available to speed up things when possible (default, use version noBlas noLapack to avoid using it), lapack to implement more complex linear algebra stuff. For sparse matrixes Bill has hidden them in the multiarray project, the multiarray implementation there is quite slow and has some shortcomings, but it hasn't been the focus of bill since a long time. But he has wrappers for sparse matrixes, and several sparse matrix libs that he actively uses. for small vectors/matrixes I use open math for games (omg) implementation. ciao Fawzi
Oct 16 2009
prev sibling parent Bill Baxter <wbaxter gmail.com> writes:
On Fri, Oct 16, 2009 at 2:57 AM, Fawzi Mohamed <fmohamed mac.com> wrote:
 On 2009-10-16 11:13:59 +0200, gzp <galap freemail.hu> said:

 language_fan =EDrta:
 Thu, 15 Oct 2009 02:04:09 -0400, Chad J thusly wrote:

 I'm reminded of how annoying it is when there are different libraries
 for a language that all define their mathematical types differently an=




 in incompatible ways (all of the Vec2D, Vec3D, etc ever). =A0Also
 aggravating is when there is one canonical type that everyone uses, bu=




 it is a poor choice (char* in C for strings).

Sometimes it feels like Vec3 must be the most reimplemented wheel on th=



 world.

Yes, i've also started to implement my own matrix/vector library, though could not get too far yet, as I have to learn D meanwhile. I've checked =


 existing ones (ex. Lyla, and some other on dsource - don't remember the
 name, sorry), but my main problem was that,

 =A0- the implementation could not be altered as desired (ex. I need a sp=


 matrix, where the matrix elements grouped using a quad-tree )
 =A0- didn't like the coding style ( ex. "_" in function names). In some
 previous post there was some discussion about this and from my experienc=


 even though we found libraries that has all the capability we required, =


 did not used them. Sometimes we didn't used our colleagues (good,
 well-planned) codes either b/c the style differed so much (ex capital
 letters, "_", m prefix for members etc.) So if a language can enforce a
 style (at least giving some warnings - and turning on treat warnings as
 errors :) ), that really helps to reuse codes. Well, it's another topic.=


 =A0- too general where it is not required for me, but could not extend w=


 it is needed for me
 =A0- seemed to be hard to implement a "general" n-d geometry lib based o=


 them(ex 2d/3d/nd ray, sphere, plane, etc, simplicals, space partitioning=


 n-d etc.)

 So it'd be really great to create a "new" d mathematical library, that i=


 developed and discussed by a group.

 Ok, I know there are wrappers for BLAS and other C libraries, but I'd li=


 to see a library written entirely in D.

I think you are greatly underestimating the effort of making "just a libr=

 for matrixes and vectors"

 I think that there are at least 3 areas that have quite different tradeof=

 * small vectors/matrixes, fixed size
 * large dense vector/matrixes
 * sparse matrixes/vectors

 I did just dense matrixes, in blip, and blas is used if available to spee=

 up things when possible (default, use version noBlas noLapack to avoid us=

 it), lapack to implement more complex linear algebra stuff.

 For sparse matrixes Bill has hidden them in the multiarray project,

Wasn't really my intention to hide them :-)... but yes they are there in the "dflat" package of multiarray.
 the
 multiarray implementation there is quite slow and has some shortcomings, =

 it hasn't been the focus of bill since a long time.

Yeh, don't use the multiarray in the multiarray project. dflat is for sparse and dense matrices and is independent of multiarray.
 But he has wrappers for sparse matrixes, and several sparse matrix libs t=

 he actively uses.

Well less actively these days since I changed jobs. But as you can see, I still hang around here anyway, just waiting for the day D declares victory.
 for small vectors/matrixes I use open math for games (omg) implementation=

Best named math library evar, probly. lol. --bb
Oct 16 2009
prev sibling next sibling parent Fawzi Mohamed <fmohamed mac.com> writes:
On 2009-10-14 23:49:07 +0200, dsimcha <dsimcha yahoo.com> said:

 I'm working on some mathy modules that I'd like to eventually contribute to
 Phobos, or, if they're too niche, to a standalone lib.  One that I've alluded
 to here in the past few days is MathExp.  Basically what it does is
 parse/interpret/evaluate/manipulate mathematical expressions at runtime.
 Here's a summary of what I've got working so far:
 
 MathExp numerator = mathExp("x^2 * cos(x)", "x");
 MathExp denominator = mathExp("exp(-x)", "x");
 MathExp ratio = numerator / denominator;
 
 // Print the result of
 // (x^2 * cos(x)) / (exp(-x)) evaluated at x = 5.
 writeln(ratio(5));
 
 // Compute a derivative symbolically.
 MathExp derivDenominator = denominator.derivative("x");
 
 I'm trying to figure out which one makes more sense in the grand scheme of
 things.  MathExp might be best kept very simple and stupid and pretty much
 left as is, possibly even with the symbolic differentiation capabilities
 removed (though these contribute surprisingly little to the weight of the
 code; I wrote most of them in one evening just to see if I could).  It would
 be easy to use, understand and debug, but be very stupid and have virtually no
 semantic understanding of the expressions it's manipulating.  It wouldn't even
 be able to simplify, for example, (1 + x + 1) -> (x + 2).
 
 On the other hand, I could take this to the nth degree and add things like
 decent printing capabilities (right now, my toString() method is a huge
 kludge, is intended for debugging purposes, and puts in tons of unnecessary
 parentheses).  I could figure out how to add some semantic analysis to
 simplify expressions, maybe symbolic equation solving in some simple cases,
 etc.  The downside to this is that I would be reinventing the computer algebra
 system in D, which might be a bit too much for a small hobby project that's
 intended as a Phobos module.  I'd likely make the code an order of magnitude
 more complicated than it is now and might end up reinventing a square wheel or
 writing some really buggy code.
 
 If the goal here is to build a Phobos module or standalone plain old library,
 do you think the KISS approach or the full-fledged approach is more useful to
 the D community?

Looks interesting, I would vote for KISS... maybe in the future with possible runtime compilation of a function... :) Fawzi
Oct 15 2009
prev sibling next sibling parent reply Bill Baxter <wbaxter gmail.com> writes:
On Wed, Oct 14, 2009 at 2:49 PM, dsimcha <dsimcha yahoo.com> wrote:
 I'm working on some mathy modules that I'd like to eventually contribute =

 Phobos, or, if they're too niche, to a standalone lib.
 One that I've alluded
 to here in the past few days is MathExp.  Basically what it does is
 parse/interpret/evaluate/manipulate mathematical expressions at runtime.

I kinda think it's too niche. A nice thing to have if you're implementing a calculator or some other program where users can input their own expressions. But other than that I can't think of any time I've run across the need to evaluate expressions at runtime. What sort of use cases did you have in mind?
 Here's a summary of what I've got working so far:

 MathExp numerator =3D mathExp("x^2 * cos(x)", "x");
 MathExp denominator =3D mathExp("exp(-x)", "x");
 MathExp ratio =3D numerator / denominator;

 // Print the result of
 // (x^2 * cos(x)) / (exp(-x)) evaluated at x =3D 5.
 writeln(ratio(5));

 // Compute a derivative symbolically.
 MathExp derivDenominator =3D denominator.derivative("x");

Not really relevant to your lib, but for cases where you have compile-time expressions and you want to evaluate the derivative at runtime, there is something called automatic differentiation tends to be much more effective than symbolic differentiation if the goal is to actually compute a numerical result. http://en.wikipedia.org/wiki/Automatic_differentiation I just think it's a neat trick, so I mention it here. :-)
 I'm trying to figure out which one makes more sense in the grand scheme o=

 things. =A0MathExp might be best kept very simple and stupid and pretty m=

 left as is, possibly even with the symbolic differentiation capabilities
 removed (though these contribute surprisingly little to the weight of the
 code; I wrote most of them in one evening just to see if I could). =A0It =

 be easy to use, understand and debug, but be very stupid and have virtual=

 semantic understanding of the expressions it's manipulating. =A0It wouldn=

 be able to simplify, for example, (1 + x + 1) -> (x + 2).

 On the other hand, I could take this to the nth degree and add things lik=

 decent printing capabilities (right now, my toString() method is a huge
 kludge, is intended for debugging purposes, and puts in tons of unnecessa=

 parentheses). =A0I could figure out how to add some semantic analysis to
 simplify expressions, maybe symbolic equation solving in some simple case=

 etc. =A0The downside to this is that I would be reinventing the computer =

 system in D, which might be a bit too much for a small hobby project that=

 intended as a Phobos module. =A0I'd likely make the code an order of magn=

 more complicated than it is now and might end up reinventing a square whe=

 writing some really buggy code.

Yeh, it sounds like it to me. Writing a serious CAS is a huge project and most of the time people who need such functionality don't really need it in library form. They need an interactive program like Maple to get some result which they then plug into their own program. If you do decide to do it, though, the SymPy project might be a nice one to look at. It's coming along quite nicely. I don't know anything about the internals, but their stated goals are to maintain readability and simplicity of the code as much as possible, even if it leads to less efficiency.
 If the goal here is to build a Phobos module or standalone plain old libr=

 do you think the KISS approach or the full-fledged approach is more usefu=

 the D community?

I'd stick with KISS unless you really want CAS to become your full-time hob= by. --bb
Oct 15 2009
parent Don <nospam nospam.com> writes:
Bill Baxter wrote:
 On Wed, Oct 14, 2009 at 2:49 PM, dsimcha <dsimcha yahoo.com> wrote:
 I'm working on some mathy modules that I'd like to eventually contribute to
 Phobos, or, if they're too niche, to a standalone lib.
 One that I've alluded
 to here in the past few days is MathExp.  Basically what it does is
 parse/interpret/evaluate/manipulate mathematical expressions at runtime.

I kinda think it's too niche. A nice thing to have if you're implementing a calculator or some other program where users can input their own expressions. But other than that I can't think of any time I've run across the need to evaluate expressions at runtime. What sort of use cases did you have in mind?

Probably the same as these: http://www.codeproject.com/KB/recipes/MathieuMathParser.aspx http://www.codeproject.com/KB/recipes/FastMathParser.aspx
Oct 15 2009
prev sibling parent Bill Baxter <wbaxter gmail.com> writes:
On Thu, Oct 15, 2009 at 4:36 AM, Don <nospam nospam.com> wrote:
 Bill Baxter wrote:
 On Wed, Oct 14, 2009 at 2:49 PM, dsimcha <dsimcha yahoo.com> wrote:
 I'm working on some mathy modules that I'd like to eventually contribut=



 to
 Phobos, or, if they're too niche, to a standalone lib.
 One that I've alluded
 to here in the past few days is MathExp. =A0Basically what it does is
 parse/interpret/evaluate/manipulate mathematical expressions at runtime=



 I kinda think it's too niche. =A0A nice thing to have if you're
 implementing a calculator or some other program where users can input
 their own expressions. =A0But other than that I can't think of any time
 I've run across the need to evaluate expressions at runtime. =A0What
 sort of use cases did you have in mind?

Probably the same as these: http://www.codeproject.com/KB/recipes/MathieuMathParser.aspx http://www.codeproject.com/KB/recipes/FastMathParser.aspx

Funny. Yes, seems they couldn't come up with any examples either. :-) --bb
Oct 15 2009