Click here to Skip to main content
15,114,611 members
Articles / Web Development / HTML
Posted 22 May 2018


18 bookmarked

Math Function Tutor: Part 2

Rate me:
Please Sign up or sign in to vote.
4.00/5 (4 votes)
22 May 2018CPOL5 min read
Math Function Tutor, Part 2

Image 1


In Math Tutor Part 1, I showed you a program created for a math student I know to study mathematical functions. Four pre-defined math functions were provided. In this Part 2, you can define your own math functions, and they will be evaluated by a Recursive Descent Parser, or RDP.

Changes from Part 1

Before we get into the RDP, here are some of the changes from Part 1:

  1. Created MathUtilLib and moved MathFunction.cs, ExtensionMethods.cs and Options.cs to it.
  2. Options now allows you to set the precision of the text box and numeric up-down controls, and the increment value of the numeric up-down controls.
  3. Added logging that utilizes the Windows Event Log; you will need admin access to your machine to use it. If you don't have admin access or don't want to use the Windows Event Log, you can modify Logger.cs in MathUtilLib to do something simple, like write logging info to a text file.
  4. Created RDPLib containing the RDP and a unit test project (more on this below).
  5. Changed the settings saving. Some reviewers thought using %userprofile%\appdata was too "Windows-centric." So, for simplicity and flexibility, the settings are saved in a text file. So now you can simply save and retrieve your settings from a regular text file using File->Save and File->Open. See the HelpFile.html available via the Menu Strip's Help->Instructions for details.
  6. Modified the UI giving the ability to Edit functions, and to Define new functions.

The Recursive Descent Parser (RDP)

For this Part 2 of the Math Tutor, I've utilized Herb Shildt's Recursive Descent Parser. Mr. Shildt's books on C and C++ introduced me to the concept several years ago, and I've modified it to be able to recognize constants and math functions like cosine and sine.

An expression parser evaluates an algebraic expression like: 1 + 2 * 3. The precedence is defined by rules known as the grammar. Thus, in the expression 1 + 2 * 3, the 2 is multiplied by 3 first, then the 1 is added, giving 7. If we use parentheses, we can force the addition to happen first, so (1 + 2) * 3 evaluates to 9. In these expressions, each component is called a token and is a string that contains at least a single character. In the above expressions, the digits 1, 2, and 3 are TokenType NUMBER, the +, - and parentheses are TokenType DELIMITER. The magic of the RDP is in RecursiveDescentParser.cs. At first, the code may seem a little daunting. But creating your own Test Methods (methods annotated with [TestMethod]) in the RDPUnitTestProject and stepping through them with the debugger is an effective way to learn how the RDP works.

The math functions (sqrt, sin, cos, etc.) are defined in Functions.cs; the constants (pi, e, G) are defined in Constants.cs. The net result of all this somewhat complex code is that you can type an expression directly into the function parameter text box like this: sqrt(3 * pi / 2), and the RDP will arrive at the right answer, namely 2.171. The RDP is not only used to evaluate expressions in the text box controls, it is also used to evaluate functions you define. Associated with each user defined function are four parameters called A, B, C and D. You set values of the parameters with the function parameter controls. So when you define your own function, you can include any of the parameters. For example, the pre-defined linear function is A * x + B where x is the value on the x axis. You can label the controls, so for the linear function, the controls associated with A are labeled "Slope", the controls associated with B are labeled "Y-intercept". Moving the track bar ("slider"), clicking the numeric up-down control, or typing a value into the text box will change the value of the respective parameter, causing the slope or y-intercept of the line to change accordingly.

Editing Functions

As with Math Tutor Part 1, there are four pre-defined math functions. However, in this Part 2, you can edit the formula and labels, and set the initial values of the parameters. See the HelpFile.html available via the Menu Strip's Help->Instructions for details.

Defining Your Own Functions

You can also define your own functions. See the HelpFile.html available via the Menu Strip's Help->Instructions for details. In brief, select Function->Manage from the Men2u Strip to display the Math Function Detail dialog, then click "Add New Function". After entering the name, formula, labels and initial values, clicking Save, then Close, the new MathFunction will be added to the list of math functions, and the new MathFunctionUserControl will be added to the FlowLayoutPanel.

Using the Code

Download and open the MathTutor.sln solution with Visual Studio. It consists of five projects:

  1. ControlLib - a library that contains a .NET User Control
  2. MathTutor - the main forms of the solution
  3. MathUtilLib - a utility library that contains, among other things, the MathFunction class
  4. RDPLib - the Recursive Descent Parser (RDP)
  5. RDPUnitTestProject - a Visual Studio Unit Test Project for the RDP

Build the solution by pressing F6.

The primary class is still MathFunction, but it differs from the previous version in that it has an instance of the RDP instead of MyFunc:

public class MathFunction
    // public Func<double, double> MyFunc { get; set; } previous version

    RecursiveDescentParser parser = new RecursiveDescentParser();

    public String Name { get; set; }
    public String Formula { get; set; }


With a little imagination, you can create some extraordinary functions. Here's one I came up with while I was testing the project: A * cos(x - B) + sqrt(abs(sin (C * x))). Start the parameter C, "sin freq", at 1.0, then click the "Start Timer" button and watch what happens.



  • Version


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Software Developer (Senior)
United States United States
Chuck Peasley is a developer in Orange County, CA

Comments and Discussions

BugCorrection to spelling of Mr. Schildt's last name Pin
charles92229-May-18 7:01
Membercharles92229-May-18 7:01 
It's Schildt, not Shildt. My apologies.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.