Introduction
In my spare time, I had wondered what it would take to create a Math
library; particularly for Algebra - just for fun. After playing with a few ideas, I came up with a solution using Regular Expressions. This article will now discuss the basic concepts behind starting to create an algebra library. Note that this is nowhere near a complete solution, but merely a pointer (pardon the pun) in the direction one could take if one wanted to create an Algebra
library using .NET.
Monomials, Polynomials and Variables
The first thing we should do is create some struct
s to represent variables, monomials and polynomials. This is what I came up with:
public struct Variable
{
public string Name { get; set; }
public int Exponent { get; set; }
public Variable(string name, int exponent)
: this()
{
Name = name;
Exponent = exponent;
}
public static Variable Parse(string item){}
public static bool operator ==(Variable lhs, Variable rhs){}
public static bool operator !=(Variable lhs, Variable rhs){}
public static Variable Empty{}
public override string ToString(){}
public class VariableCollection : List<Variable>
{
public bool ContainsVariableName(string name){}
public bool Equals(VariableCollection v2){}
public override string ToString(){}
}
This is the basic component, a Variable
class. The "Name
" property is the variable name "x
" or "y
", etc. The exponent is literally just that. You can see that there are some operator overloads to check whether or not two variables are equal or not. This will come in handy when trying to determine whether two variables can be added together or if they're incompatible.
public struct Monomial
{
public double Coefficient { get; set; }
public VariableCollection Variables { get; set; }
public int Exponent { get; set; }
public static Monomial Parse(string item){}
public static string operator +(Monomial addend1, Monomial addend2){}
public static string operator -(Monomial minuend, Monomial subtrahend){}
public static string operator *(Monomial factor1, Monomial factor2){}
public static string operator /(Monomial dividend, Monomial divisor){}
public static string Add(Monomial addend1, Monomial addend2){}
public static string Subtract(Monomial minuend, Monomial subtrahend){}
public static string Multiply(Monomial factor1, Monomial factor2){}
public static string Divide(Monomial dividend, Monomial divisor)[]
public override string ToString(){}
}
The Monomial
class above is made up of the coefficient, a collection of variables and its own exponent. For example (x^4yz^13)^2
could be a monomial where x
and yz
are the variables that have their own exponents (4
and 13
respectively) and the exponent 2
applies to the entire monomial. This is the main class, where all the heavy duty stuff is done. Here we have operator overloads for adding, subtracting, multiplying and dividing monomials together. Note: As I could not find a way to insert superscript, I will be using the character '^' to represent an exponent (to the power of).
public struct Polynomial
{
public IEnumerable<Monomial> Monomials { get; set; }
public static Polynomial Parse(string item){}
}
This one is just a collection of monomials really, as one would expect.
Note: See actual code (http://algebralib.codeplex.com/) for implementation of the above methods. Here I am just providing the signatures for clarity.
Regex Patterns
Next, we need to specify some regex patterns to match user's input strings:
internal static Regex IntegerPattern =
new Regex(@"(\+|-)?[1-9]+", RegexOptions.Compiled);
internal static Regex VariablePattern =
new Regex(@"[a-zA-Z]+", RegexOptions.Compiled);
internal static Regex CoefficientPattern =
new Regex(@"(?<value>(?<sign>((\+|-)?))\b(?<coef>([0-9](\.)?)+))[a-zA-Z]",
RegexOptions.Compiled);
internal static Regex VariableWithExponentPattern =
new Regex(@"([a-zA-Z]+-?(([1-9])*)?)(?![a-zA-z])*", RegexOptions.Compiled);
internal static Regex MonomialPattern =
new Regex(@"(([1-9]*)?([a-zA-Z])+-?([1-9]*)?)+", RegexOptions.Compiled);
These patterns are used to parse the user's input. For example, the MonomialPattern
pattern will match a monomial. The IntegerPattern
pattern will match an integer (ignoring anything else) and so forth.
Using the Code
Now that we can parse monomials and have the methods in place to add, subtract, multiply or divide them, we need some way to display this nicely to the user. See the screenshot below:
This calculation was produced by the following event handler:
private void btnCalculate_Click(object sender, EventArgs e)
{
Monomial m1 = Monomial.Parse(txtValue1.Text.Trim());
Monomial m2 = Monomial.Parse(txtValue2.Text.Trim());
switch (cmbOperation.Text)
{
case "+": subSupLbl.Text = m1 + m2; break;
case "-": subSupLbl.Text = m1 - m2; break;
case "*": subSupLbl.Text = m1 * m2; break;
case "รท": subSupLbl.Text = m1 / m2; break;
default: break;
}
}
To display superscripts properly to the user, I used the subscript-superscript label from here.
Note: As I was writing this article, it seems the aforementioned site is now down. Not sure if it will be back, but my thanks to whoever he was for writing this control and for saving me the time!
Conclusion
There's a lot of work to be done still. For example, it is possible to have a variable as an exponent, in which case any real world app would not have the Exponent
property set to an int
.
Feel free to take this further if it suits your fancy; I would love to see how far this can go. :)
History
- 18th October, 2010: Initial post