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

- dsimcha <dsimcha yahoo.com> Oct 14 2009
- Chad J <chadjoan __spam.is.bad__gmail.com> Oct 14 2009
- language_fan <foo bar.com.invalid> Oct 15 2009
- gzp <galap freemail.hu> Oct 16 2009
- Fawzi Mohamed <fmohamed mac.com> Oct 16 2009
- Bill Baxter <wbaxter gmail.com> Oct 16 2009
- Fawzi Mohamed <fmohamed mac.com> Oct 15 2009
- Bill Baxter <wbaxter gmail.com> Oct 15 2009
- Don <nospam nospam.com> Oct 15 2009
- Bill Baxter <wbaxter gmail.com> Oct 15 2009

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

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

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

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

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

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

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

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

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

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