View Full Version : Expression Manipulator v0.1

ygfperson

05-15-2003, 11:37 PM

It's finally here... after a month... :D

It's got plenty of bugs to be worked out... but this is pretty far along from my last release.

This is a set of classes designed to manipulated Expressions, functions, and what-have-you.

Features:

Expressions can be typed in almost as they would be on a graphing calculator

The classes are const-protected; with private parts protected

It will accept equations, too, if the program detects an equals sign

It can combine like terms and like factors easily

it can distribute factors, FOIL them, or expand them according to exponents. (It's not limited to FOIL; it can multiply any number of terms)

There is buggy and limited support for trig functions (sin, cos, tan, cot, sec, csc)

There is the ability to define functions in run-time; though the command-line isn't ready for it yet. (You can manually experiment from int main(), though)

Every function has a domain, and several pieces of domain can be combined to get a whole domain (see code for details)

The classes are organized by file this time

expandable framework

Any questions? I haven't attached an executable yet, but I may in the morning.

Sang-drax

05-16-2003, 12:01 PM

Could you provide a short code example showing how it is used?

ygfperson

05-16-2003, 01:04 PM

after it is compiled, run it, and type in an expression:

9x^2+b

and it will parse it into objects and print it back out again. If there's a way to simplify it, it will do that automatically. ie:

9(x+3)^2

9x^2 + 54x + 81

note: minus signs must have a space after them, otherwise they'll be counted as negative signs

For examples of its use in code, look at int main()

(located in expression.cpp)

Sang-drax

05-16-2003, 02:16 PM

Ahh, I missed the main() function.

These are the changes I had to make to make the code compile in MSVC++.NET:

Added lines to Expression.h

#include <algorithm>

#include <cmath>

using std::sort;

using std::cos;

using std::sin;

using std::tan;

using std::log;

#include <limits>

namespace

{

const double INFINITY = std::numeric_limits<double>::infinity();

}

Added lines to Expression.cpp

const double Float::EPSILON = 0.0000000000001; //double is not an integral type -- inline definition not possible

I also had to add return *this at numerous places where it had been omitted.

At one place (Term::return_first_factor()) I couldn't add "return *this" so I added a throw-statement instead.

Now I'll try the program.

Sang-drax

05-16-2003, 02:30 PM

The simplifying seem to work, I've tested it with some expressions.

If the string "(5)" is entered, the output will not be the same as if "5" is entered, but it could be me not understanding the output.

ygfperson

05-16-2003, 08:40 PM

You're right... I didn't notice that. That's a bug.

Here is the executable:

//edit: another note: make sure there is a '*' between a variable and a parentheses. ie:

f(x)

will be interpreted as the function 'f' with parameter 'x'.

f*(x)

is f * x.

XSquared

05-16-2003, 09:05 PM

It has the wrong output for (x-y)^2

XSquared

05-16-2003, 09:07 PM

Whoops. Nevermind. Forgot about the whole 'space after a minus sign' thing.

vasanth

05-17-2003, 10:23 AM

Can u post the binary please.. could not compile the file

Commander

05-17-2003, 12:15 PM

this is WAYYYYY better then i thought it would be!!!!!

great job man!!

XSquared

05-17-2003, 04:02 PM

Originally posted by vasanth

Can u post the binary please.. could not compile the file

He did at the end of his last post.

Magos

05-17-2003, 04:31 PM

Nice. A few thoughts/bugs:

1) Why is the result printed 4 times? I also noticed that (sometimes) the last two were the 'reverse' of the first two.

Did you use different methods of simplifying the expression, or?

5 + x = 5 + x

5 + x = 5 + x

x + 5 = x + 5

x + 5 = x + 5

2) Sometimes a "+0" or a "*1" is inserted:

Input: (x) = z

x = z

x = z

x + 0 = z

x + 0 = z

Input: f(x) = (f(x + h) - f(x)) / h

f(x) = 1*f([x + h]) + -f(x)*h

f(x) = 1*f([x + h]) + -f(x)*h

f(x) = 0+f([x + h]) + -f(x)*h

f(x) = 0+f([x + h]) + -f(x)*h

Otherwise it seems to work ok.

ygfperson

05-17-2003, 07:48 PM

Originally posted by Magos

Nice.

Thanks.

A few thoughts/bugs:

1) Why is the result printed 4 times? I also noticed that (sometimes) the last two were the 'reverse' of the first two.

Did you use different methods of simplifying the expression, or?

Yes, actually. Sorry for burying int main() in there.

1) Expression after being parsed (unsimplified)

2) Combined like terms and factors

3) Used distributive property to expand factors

4) Evaluated simple functions like trig funcs and logs

That's the gist of it. #4 doesn't work for much of anything more than sin(cos(0)) or sin(3.14) or cot(1)... etc...

2) Sometimes a "+0" or a "*1" is inserted:

Input: (x) = z

x = z

x = z

x + 0 = z

x + 0 = z

Input: f(x) = (f(x + h) - f(x)) / h

f(x) = 1*f([x + h]) + -f(x)*h

f(x) = 1*f([x + h]) + -f(x)*h

f(x) = 0+f([x + h]) + -f(x)*h

f(x) = 0+f([x + h]) + -f(x)*h

Otherwise it seems to work ok.

The '*1' and the '+ 0' are side-effects of the simplification. The function 'clear_extra' should get rid of them, but I haven't put it in int main() because I haven't seen a need to.

BTW, There's a parsing bug I just found out from your output... don't put any whitespace between the '/' and its factors. I'll fix this in the next release so that your input would work.

Sang-drax

05-18-2003, 04:19 AM

Yeah, you should enhance your parser.

x(y+z)

x*-y

(a+b)(c+d)

should be possible

XSquared

05-18-2003, 06:20 AM

x*(y+z)

x*-y works fine.

(a+b)*(c+d)

Sang-drax

05-18-2003, 07:22 AM

Yes, I know those circumventions are possible, but the computer should adapt to the user, not vice verca.

The user should not have to remember to add an extra space after a minus sign.

ygfperson

05-18-2003, 09:53 AM

(a+b)(c+d) does work fine. In some situations the parentheses surrounding the expression don't show when they should, so I'll have to tweak that.

x(a+b) isn't allowed because x() is handled like a function. Graphing calculators have the same problem. The only way I can see to allow that is to differentiate between functions and variables at run-time, which means pre-defining the names of each before using them.

I might be able to tweak minus signs to work correctly in situations. Graphing calculators solve this problem by having a different minus sign than their negative sign. Anyone have any ideas for rules regarding the dash? (ie: if letter before and afterwards, it's a minus sign)

XSquared

05-18-2003, 10:05 AM

Wouldn't it always be possible to interpret it as a negative sign?

4-n = 4+(-n)

ygfperson

05-18-2003, 01:22 PM

Originally posted by XSquared

Wouldn't it always be possible to interpret it as a negative sign?

4-n = 4+(-n)

But that could also be

4-n = 4(-n)

confuted

05-18-2003, 01:59 PM

Most people would probably write that as 4*-n though, or use 4(-n). I don't think anyone would type 4-n and intend 4 times negative n.

edit: impressive program anyway

ygfperson

05-18-2003, 04:34 PM

so... ignoring whitespace, it's a minus sign unless

1) It's preceded by a plus sign

2) it's preceded by a parenthesis

3) it's the first character in the string

4) it's preceded by a '*'

This sound good?

thanks for your input, btw

confuted

05-18-2003, 05:00 PM

That sounds excellent

XSquared

05-18-2003, 08:12 PM

So you can't divide by a negative number, according to your rules...

ygfperson

05-18-2003, 08:44 PM

Originally posted by XSquared

So you can't divide by a negative number, according to your rules...

5) It's preceded by a '/'

BTW, the '/' serves to raise the next factor in the string by -1 power. Negative signs are skipped past, because there's never any intention to divide just by a negative 1.

Powered by vBulletin® Version 4.2.5 Copyright © 2019 vBulletin Solutions Inc. All rights reserved.