Re: Perl and maths
by rg0now (Chaplain) on Feb 15, 2005 at 11:15 UTC
|
So you want symbolic math? Then you might want to look into Math::Symbolic. Seems pretty promising, although I myself have never tried it. For me, Mathematica from Wolfram Research proved to be unbeatable, although it is a commercial software...
| [reply] [Watch: Dir/Any] |
Re: Perl and maths
by Courage (Parson) on Feb 15, 2005 at 12:31 UTC
|
I suggest using Maxima, which has strong connection to Tcl and also has Tcl/Tk GUI frontend.
See information about Maxima and its usage from Tcl at http://mini.net/tcl/4758
you could feed maxima.exe with your data and read results This involves 2-way pipes
Another approach could be to start Tcl/Tk GUI for maxima and manipulate this GUI from Perl to get your results.
addition 1,2:
I get my 2nd way to work, but this required some Tcl touches and looking Tcl/Tk wiki for some Maxima connection details.
But finally I got Perl+Tcl/Tk gui with a button that do symbolic algebra computations
use strict;
use Tcl;
use Tcl::Tk;
my $int = new Tcl::Tk; # this one for Maxima GUI
my $int2 = new Tcl::Tk;
my $mwm = $int->mainwindow;
my $mw = $int2->mainwindow;
# get maxima
$int->Eval('source xmaxima0');
$int->Eval('source m0.tcl');
# do our GUI
my $text_res;
my $str = 'integrate(1/(1+x^3),x)'; # text example for maxima expr
$mw->Entry(-font=>'Courier 12',-textvariable=>\$str)->pack(-fill=>'x')
+;
$mw->Button(-text=>'Do it!',-command=>sub {
$text_res->insert('end',''.$int->domax($str));
$text_res->seeEnd;
})->pack;
$text_res = $mw->Scrolled('Text',-font=>'Courier 12')->pack;
$mwm->withdraw;
$int2->MainLoop;
$mwm->destroy;
Happy screenshot at http://www.vkonovalov.ru/xmaxima-scr.jpg | [reply] [Watch: Dir/Any] [d/l] |
Re: Perl and maths
by blazar (Canon) on Feb 15, 2005 at 10:05 UTC
|
Well this may soon become of a formidable complexity. For one thing you should do the parsing of the expressions in the first place. I'm not even trying to do anything like that because admittedly I have no experience at all in this field. However as a general direction you may either roll-your-own solution or design a very simplified grammar with e.g. Parse::RecDescent.
IIRC something roughely along these lines had been discussed on clpmisc short before I stopped regularly following it.
As far as the (Tk) UI is concerned, it's simply up to you and to your skills and tastes, however this seems to me like a task well suited for a cmd-line console based UI, so if you really want to go graphical, then probably something as simple as a window with an input field, a text field for output and an update button would suffice.
UPDATE: Now that I re-read this, I realize that you were most probably referring to the formatting of mathematical expressions. Then in practice you're asking about implementing a typesetting engine, even if you may be content with an elementary one. In any case it won't be an easy task. I recommend you give a peek into the (La)TeX world instead. In particular you may be interested in mimeTeX and preview-latex. | [reply] [Watch: Dir/Any] |
Re: Perl and maths
by Hena (Friar) on Feb 15, 2005 at 09:50 UTC
|
I think this would easily get complicated. Only thing that I can come up with is that you need functions to take that input apart. Eg. array with one element that has one calculation each. Remember that order needs to be two fold, order in line and order to do the calculation. Also function that parses your array back into printable line.
Then you just do one calculation for each element and print out whats between. Since I'm at office, I'm not going to start coding, but thats a how i would start doing something like this. Note that since I haven't done any Perl/Tk stuff, i can't comment on how that should be done. Good luck :). | [reply] [Watch: Dir/Any] |
Re: Perl and maths
by halley (Prior) on Feb 15, 2005 at 14:47 UTC
|
I wanted to code something like this twenty years ago. It would have been cumbersome in C but I think a lot more do-able in a reasonable effort in Perl.
The task is really just a bunch of simple text (or tree) transforms, and a set of rules on how to apply them. It has very little to do with math itself.
There are several symbolic math engines out there, but they usually skip the step-by-step proof production. They simplify the expression as far as possible, and stop. If you have source code to these engines, it should be trivial to break it up into an iterative process, returning a set of proof production steps.
Each rule would have a pattern it looks for, and a replacement pattern. Rules should be simple and ordered. Rules should be scanned in the order they are asserted. (Hey, this is sounding more like Prolog now.) Each time you apply a rule successfully, you should start at the top again to see if it can be simplified further.
For maximum benefit, each production in the proof should also explain the mathematical rule it applied. For instance:
(a*(b+c))
(a*b + a*c) -- distribute a to terms b and c
(Sheepishly, I tried to look up an official name for that simple transform on Wolfram's site, but came up empty. Apparently, if it's not some tensor product of primoral eigenvalues, it's too simple for Wolfram to discuss.)
-- [ e d @ h a l l e y . c c ]
| [reply] [Watch: Dir/Any] [d/l] |
|
This is the distributive property of multiplication
-j
| [reply] [Watch: Dir/Any] |
|
Yep, I once wrote something like this in Prolog as an assignment. I don't remember the details and the code is long lost though. Anyway if I were to do it again (and had to implement it myself) I'd definitely use Prolog again. It does take some time to get used to it since you really have to think differently than when using imperative languages, but once you get the twist it's great for this kind of tasks.
Jenda
We'd like to help you learn to help yourself
Look around you, all you see are sympathetic eyes
Stroll around the grounds until you feel at home
-- P. Simon in Mrs. Robinson |
| [reply] [Watch: Dir/Any] |
|
this almost looks like you are getting into sentential and predicate logic, although not quite, but it could be considered a basic proof to go from (5/3 + 7/13)/(5/2 - 3/7) to 1204/1131 (is that the right answer?). just a thought...
| [reply] [Watch: Dir/Any] |
Re: Perl and maths
by artist (Parson) on Feb 15, 2005 at 14:48 UTC
|
I think that, I know what you are after. It would be fun to see math equations solved step by step automatically. Your input is an equation and as output you want to get step by step answers. You need to define the steps and precedence. In the case you have presented, for example, you might want to do cross multiplication of the numbers within the parantheis and then remove the paranthesis and make it more simple before getting the final answer. It would be fun to define all these rules for different equations. Once you do that, you will have better control of working of math euqation and will serve a useful aid in your teaching.
For coding these, you may define each element as a seperate entitiy in your euqation. Parse::RecDescent would be very useful for this. Once you have elements and their positions within equation, you may apply your rules to create the next step and so on.
| [reply] [Watch: Dir/Any] |
Re: Perl and maths
by Animator (Hermit) on Feb 15, 2005 at 10:42 UTC
|
If that is the way you're explaining it to her, then I would say: stop.
perl -wle 'print ((5/3 + 7/13) / (5/2 - 3/7));' ==> prints 1.06454465075155
perl -wle 'print ((39 + 3 /13) / (35 - 9/21));' ==> prints 1.1347743165925
Are you sure you know math? Or is it Perl that doesn't know math? :)
Now back on topic, are you looking for a fully-featured calculator? or just a basic one (one that can only handle +, -, *, /)?
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
no, I don't try it to explain her maths using Perl, ....
I'm trying to have fun for myself
I'm not searching a calculator either. I don't also want to deal with 0.3333 if I mean 1/3. You remember when you went to school ? I wish to transform ( for beginning ) simple expressions. cheers, reinhard
| [reply] [Watch: Dir/Any] |
Re: Perl and maths
by hardburn (Abbot) on Feb 15, 2005 at 16:49 UTC
|
And they shall call it "LISP" :)
Really, run through the first chapter of SICP, which shows how each step of a LISP computation (well, Scheme technically) is performed until you get the basic answer. One could build an interpreter that takes a basic LISP expression (you don't need a full LISP, just the basic arithmatic operations are enough), and then show the reduction of each step until you get the final answer.
You'll have to live with prefix-notation instead of the common infix notation, but I think we need more of that, anyway.
"There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.
| [reply] [Watch: Dir/Any] |
Re: Perl and maths
by tall_man (Parson) on Feb 15, 2005 at 16:28 UTC
|
Here's something you could get working very quickly, without a lot of coding. Use bigrat to work with fractions, and let perl itself parse the math. You will have to break up the parts into stages, though, so it doesn't do all the simplifications at once. Here is an example:
use strict;
use bigrat;
my ($x, $y);
$x = 5/3 + 7/13;
print $x,"\n";
$y = 5/2 - 3/7;
print $y,"\n";
print $x/$y,"\n";
This prints:
86/39
29/14
1204/1131
With a loop to read expressions from input and an eval statement, you could get a perl fractional calculator going in no time. | [reply] [Watch: Dir/Any] [d/l] [select] |
Re: Perl and maths
by Grundle (Scribe) on Feb 15, 2005 at 20:07 UTC
|
Why not just break up the mathematical expression into in a tree? Then you can "percolate up" the tree generating the new expression line by line. The first line printed by perl would be all the leaf nodes with their conecting operator signs (+-*/).
The second line would be the leaf node operations completed and so on until you only have a root
You would basically need 2 routines.
1. Build-Tree -> responsible for taking an expression and making a tree out of it
2. iterate-tree -> responsible for performing the mathematical operations described at leaf level and replacing the parent node with the new answer.
i.e.
<some-root> <some-root>
/ /
+ => 9
/ \
5 4
Printing intermediate results is a breeze since it is in tree form. Just make sure that you adhere to the same principle you used when generating the tree (in-order, pre-order, or post-order). | [reply] [Watch: Dir/Any] |
Re: Perl and maths
by Anonymous Monk on Feb 15, 2005 at 11:03 UTC
|
What do you mean, "produce Perl line by line"?
(5/3 + 7/13)/(5/2-3/7) and (39 + 3/13)/(35-9/21) are valid Perl expressions.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
I admit, I was not clear
You remember at school ?
The teacher gave you an expression
and you transformed it step by step into
a simpler one , at the end remained a "nice" result
or at least it should ....
That's what I'm trying to simulate ..
cheers reinhard
| [reply] [Watch: Dir/Any] |
|
I believe you mean you would like to have perl 'simplify' the expression. Although, typically these expressions have variables. On the other hand, is this to teach 'order of operations'?
| [reply] [Watch: Dir/Any] |
Re: Perl and maths
by pingo (Hermit) on Feb 15, 2005 at 16:29 UTC
|
If you use KDE and can live with a really (really) basic interface, you could try using kdialog (I assume there is something similar for Gnome).
$val = `kdialog --title "Question" --inputbox "What is $a x $b?"`;
if ($val == $correct) {
system("kdialog --msgbox 'Correct!'");
}
else {
system("kdialog --msgbox 'Wrong!'");
}
I've used it for a math quiz thingy which was fairly successful. :-) | [reply] [Watch: Dir/Any] [d/l] |
Re: Perl and maths
by sleepingsquirrel (Chaplain) on Feb 15, 2005 at 18:00 UTC
|
Here are the beginnings of a brief skeleton of an evaluator for simple (and fully parenthesized) arithmetic expressions to get you started. It prints out all of the intermediate steps before it gets to the final answer. You'd need to swizzle the results around to get exactly what you wanted, but I think you get the idea...
((1+2)+((3+4)+(5*6)))
1 + 2 = 3
3 + 4 = 7
5 * 6 = 30
7 + 30 = 37
3 + 37 = 40
Final Answer: 40
-- All code is 100% tested and functional unless otherwise noted.
| [reply] [Watch: Dir/Any] [d/l] |
|
Here's a modification to my code above which handles adding fractions and printing out the partial results. Finishing it off is left as an exercise to the reader...
(1/2+2/3)
7/6
(1/2+(2/3+4/5))
(1/2+22/15)
59/30
((5/3+7/13)+(5/2+3/7))
(86/39+(5/2+3/7))
(86/39+41/14)
2803/546
-- All code is 100% tested and functional unless otherwise noted.
| [reply] [Watch: Dir/Any] [d/l] |
Re: Perl and maths
by Jaap (Curate) on Feb 15, 2005 at 16:28 UTC
|
It would help to get your example right. What is this?
(5/3 + 7/13)/(5/2-3/7)
and let them perl produce line bye line
(39 + 3/13)/(35-9/21)
Did you mean this?
(65/39 + 21/39)/(35/14 - 6/14)
Edit: fixed typo: thanks Paulster2 | [reply] [Watch: Dir/Any] |
|
| [reply] [Watch: Dir/Any] |
Re: Perl and maths
by tphyahoo (Vicar) on Feb 15, 2005 at 16:18 UTC
|
If you're practical, excel.
If you're aesthetical, and you can afford the price, Mathematica.
If you're full of hubris.... hell, why not... perl! | [reply] [Watch: Dir/Any] |
Re: Perl and maths
by mrborisguy (Hermit) on Feb 15, 2005 at 17:28 UTC
|
i think i would start with creating a module for fractions, with, and probably with a function that does all of the operations of fractions (add, subtract...). maybe you'll have to make it output the common denominator step inside the module though. so then you have something like ($frac1 + $frac2) / ($frac3 + $frac4) where $frac\d is of the type of your new fraction module. and then you might end up with another fraction... where $new_fraction's numerator is ($frac1 + $frac2) and it's denominator is ($frac3 + $frac4).
so (obvioulsy implementation is up to you) i would think of something a data structure for fraction as a hash with numerator and denominator, and your $new_fraction would be something like:
$new_frac => {
numerator => "5/3 + 7/13",
denominator => "5/2 - 3/7"
}
and then eventually something like
$new_frac => {
numerator => {
numerator => 86,
denominator => 39
},
denominator => {
numerator => 29,
denominator => 14
}
}
come to think of it, you may need to have a data structure or module to represent an "expression" too.
also, to parse the expression, you may want to look at postfix (although you can certainly still output the expressions in infix)
these are just my thoughts on how i'd approach it. | [reply] [Watch: Dir/Any] [d/l] [select] |
Re: Perl and maths
by samizdat (Vicar) on Feb 15, 2005 at 19:05 UTC
|
As rg0now and hardburn have alluded to, such coding has been done. For a historical referent, look up MACSYMA, which does what you want and much more, including much of Calculus and DiffEq. The original LISP code was floating around an MIT server at one time... it's really elegant.
Math::Symbolic can be whacked to print your intermediate results. | [reply] [Watch: Dir/Any] |
Re: Perl and maths
by chas (Priest) on Feb 16, 2005 at 04:32 UTC
|
One problem that occurs to me is that there are many ways of "simplfying" such mathematical expressions, and it would be very difficult to formulate rules to choose an efficient sequence of simplifications. For example one could proceed
by simplifying the "innermost" expressions and proceed outward, but that might be very inefficient in some cases.
I.e., if we had an expresion of the form:
(a+b)(c+d)+(a+b)(e+f)+(a+b)(gh+ij+kl) then one should clearly factor out (a+b) first instead of computing a+b 3 times. Of course, one could just formulate some simplification scheme, but it might not be at all like what one would do in practice in many cases.
Maybe I didn't understand what you wanted to do completely,
though.
chas | [reply] [Watch: Dir/Any] |
|
Yes. You're rigth. There are many ways of solving such an equation.
So it would also be great to have an interactive tool to follow up the semplification.
Furthermore sometimes we just see the most elegant way to perform semplification. I do not expect me from a programming language to "Just See" the correct way.
Getting philosophical now ????
However putting together a little bit of what I understood:
-- first we have to parse the formula
-- then we have to project the formula onto an internal representation ( a tree with single objects representing the numbers, maybe one object holding the fraction ? )
-- present this graphically shouldn't be so difficult.
-- Ask the user how to proceed further
-- present the result of the semplification choosed by the user
-- ask again the user for the next step
present .......
-- and so on
cheers reinhard
| [reply] [Watch: Dir/Any] |
Re: Perl and maths
by saintmike (Vicar) on Feb 16, 2005 at 07:40 UTC
|
Math::Algebra::Symbols helps with these kinds of algebra tasks. It can also solve equations (even quadratic ones!). Here's an article (sorry, German only!) showing a couple of examples. | [reply] [Watch: Dir/Any] |