GithubHelp home page GithubHelp logo

michalkonecny / robust-plots Goto Github PK

View Code? Open in Web Editor NEW
1.0 1.0 0.0 865 KB

Web app to plot robust enclosures of function graphs and fractals

License: BSD 3-Clause "New" or "Revised" License

Dhall 0.97% PureScript 98.65% JavaScript 0.12% HTML 0.26%

robust-plots's Introduction

Robust plots

Web app to plot robust enclosures of function graphs and parametric curves.

Try it now!

Examples

The above images are that of the graph y=max(0,x*sin(4/(x^2)))+1/20. The left images shows the rough version and the right shows the robust one. The robust version was obtained by drawing shapes that reliably enclose the exact objects. In particular, rounding errors are correctly accounted for. These graphical enclosures can be computed to an arbitrarily high accuracy. In the case of above it was to a 10th of a pixel. In the images below the same objects are plotted with a low accuracy so that the shapes are easy to see. In this case accurate to 10 pixels.

Further documentation

robust-plots's People

Contributors

michalkonecny avatar

Stargazers

 avatar

Watchers

James Cloos avatar

robust-plots's Issues

Sub expression simplification

Details:

Hours Spent: 16

Background

Optimal performance is required. Can be developed in tandem with #30

Overview

Add the concept of a complex expression. When an expression has repeated subexpressions, instead of evaluating the value of that subexpression repeatedly, substitute an ExpressionVariable for that subexpression that can be evaluated along the side the overall expression.

Create a subexpression map that holds the expression that the variable is masking and the expression that it is used in ExpressionLet VariableName Expression Expression
which means let x = a in b. Where a is the subexpression and b is the parent expression.

Prefix all sub-expression variables with $ and the Expression.Simplifier module should be used before joining the common subexpressions.

Example1:
sin(sin(x)) + sin(x)
becomes
let $v1 = sin(x) in let $v2 = sin($v1) in let $v3 = $v2+$v1 in $v3

Example 2:
sin(sin (sin(x))) + sin (sin(x)) + sin(x)
becomes
let $v1 = sin(x) in let $v2 = sin($v1) in let $v3 = sin($v2) in let $v4 = $v3+$v2 in let $v5 = $v4+$v1 in $v5

Algorithm:

  1. Construct a set of sub-expressions (OR map from sub-expressions to occurrence count)
  2. Assign numbers to all these sub-expressions, ie convert the set to indexToSubExpressionMap :: Map Int Expression
  3. Invert this mapping, ie create subExpressionToIndexMap :: Map Expression Int
  4. Substitute in indexToSubExpressionMap :: Map Int Expression top-level sub-terms with variables, giving indexToSubstitutedExpressionMap :: Map Int Expression, eg:
    BinOp Add expr1 expr2 -> BinOp Add (Var "$v10") (Var "$v22")
    BinOp Add (Var "x") expr2 -> BinOp Add (Var "x") (Var "$v22")
  5. Order the variables by dependency, creating sortedIndexAndSubstitutedExpressions :: Array (Tuple Int Expression) in multiple passes, starting with indexToSubstitutedExpressionMap, removing expressions that only contain known variables until the map is empty

Acceptance Criteria

  • Add joinCommonSubExpressions function that will convert the example expressions into their simplified versions
  • This function is covered by unit tests

Closing Notes

Overview of changes can be found in PR #47

The algorithm implemented is as follows.

  1. Split the expression into splitSubExpressions
    Subexpressions are unary and binary operations. This means that the expression ExpressionLiteral 40 has no sub-expressions and is not a subexpression itself.
  2. Create the subExpressionToVariableMap
    In this map the subexpression as the key and the variable as the value. This map is biopic meaning that both the key and value in each entry are unique in the map.
  3. Substitute the variables into each of the sub-expressions
    Each subexpression is either a unary or a binary operation. This means that they are expression trees that are only at maximum one deep. In this step, each entry in the map is treated over and the nested operation(s) in the unary and binary operations are looked up in the subExpressionToVariableMap. If they are found they are replaced with their respective variable.
  4. Order the entries by their interdependencies
    This works by recursively removing variables that are not dependent on any other sub-expressions in the subExpressionToVariableMap. This results in an array of the entries in the order that they should appear in the nested ExpressionLet chain.
  5. Rebuild the expression as an ExpressionLet chain
    This simply folds the chain of sub-expressions into a single expression tree. If there are no sub-expressions in the subExpressionToVariable array then the original expression is used.

There are some small differences between what the examples expect and what is produced by this algorithm. The only real difference is that there is no subexpression variable used for the top-most subexpression.

  • sin(sin(x)) + sin(x) becomes
    let $v1 = sin(x) in let $v2 = sin($v1) in $v2+$v1
  • sin(sin(sin(x))) + sin(sin(x)) + sin(x) becomes
    let $v1 = sin(x) in let $v2 = sin($v1) in let $v3 = sin($v2) in let $v4 = $v3+$v2 in $v4+$v1

I did have to update the Expression.Simplifier as now that the definition for Expression has 5 data constructors doing nested pattern matching causes a warning.

Smoother approximate plots

Details:

Hours Spent: 6

Background

Where the function has a large (positive or negative) second derivative, the approximate plot is visibly inaccurate, eg:
Screenshot_20200530_000637

Overview

Evaluate not only the function but also its second derivative in x and use this information to determine how many points to plot in which part of the x domain.

This could be achieved simply by an adaptive bisection of the domain of x into segments, bisecting deeper where the second derivative has been observed to be higher at the current segment endpoints.

Acceptance Criteria

  • We can evaluate the second derivative of expressions
  • Plots do not look much worse than Fooplot's, eg for sin(200*x) and sin(1/x^2)

Closing Notes

Overview of changes can be found in PR #40

image

image

Separate canvas state from internal state

Details:

Hours Spent: 0

Background

The visual state of the application is coupled with the state of the computations that are being computed. This cannot be the case for the structure defined by the architecture diagram.
Architecture-Runtime-Data

Overview

Define a UI state which contains all the view data that the user can interact with. In addition to this, define a 'background' state that contains the data that is not displayed to the user.

Acceptance Criteria

  • The UI state only contains the input field data and the definition of all the graph commands to be drawn on the plot.

Closing Notes

This issue was completed as part of #6

Draw gridlines

Details:

Hours Spent: 8

Background

Extension from #6.

Overview

The user needs to be able to see the gridlines displayed on the canvas for the plot. This should be based on a domain that is stored within the halogen state.

Acceptance Criteria

  • The user can see a canvas that shows gridlines between -1 and 1 at 0.1 intervals.

Closing Notes

Overview of changes can be found in PR #12

Support for the drawing the grid lines required adding support of significant figures and more complex rounding. The main module for doing this is Data.Decimal, the only problem is that Data.Decimal depends on decimal.js which is an external JS library. PS does not support importing external JS libraries and if they are used in FFI modules they are ignored at compile time. This means that the application will build but the web page will throw an error when loaded as it cannot find the JS libraries.

To solve this I had to integrate parcel into the build process as this will bundle the compiled PS and the external JS libraries together into a single bundled JS file. It should be noted that the outputted bundle file is automatically minified. Instructions for how to add external JS libraries for future reference has been added to README.md.

Now when the application is built it is built as a web application which means that it uses relative paths for the bundled JS file. To fix this simply go into the dist/index.html and find the <script> tag the app.js file is included. Then remove the / from the front of the file name.

The drawing grid line functions contain a lot of manic numbers in that the padding for the labels and the styles of the lines is fixed in the draw functions. In the future this will have to be specified in some kind of type that is specified at the DrawCommand DSL level.

Add Zoom in/out

Details:

Hours Spent: 2

Background

The previous version of this application had support for the user to zoom in and out of the plot. This functionality is required in this version also.

Overview

On the surface zoom is a very simple operation. Simply redraw the canvas for a different XYBounds. The complicated part is that the zoom functionality should only recompute parts of the plot that are visible but were not visible before zooming. This will require optimising at a later date as more complex functions are plotted and the performance needs to be improved.

For this issue, simply add a button for zooming in, and a button for zooming out. When either is pressed the currently drawn draw operations could be passed to the computePlot function. This should mean that if there are any draw operations that can be reused then there is support for adding that in place.

Acceptance Criteria

  • Add zoom in button that when pressed zooms in the canvas by 10%
  • Add zoom out button that when pressed zooms out the canvas by 10%
  • Update the compute plot function to use the previously cached draw commands.

Closing Notes

Overview of changes can be found in PR #17

The zooming is really simple in that it just changes the bounds and then redraws the previous plot. This can be changed later as needed.

image

Integrate Halogen

Details:

Hours Spent: 2

Background

Halogen is one of the most common view frameworks for PS. It can easily have an HTML canvas integrated into it allowing the plot area to be implemented. See Halogen

Overview

The first step to implement reach the goals of M1 is to have halogen integrated into the project so that the user can view a web page and the PS is bundled correctly.

Acceptance Criteria

  • User can view a webpage that is constructed using halogen
  • Code is bundled into a single JS file

Closing Notes

Overview of changes can be found in PR #11

Add custom bound input

Details:

Hours Spent: 3

Background

In the previous version of the application, the user could specify custom bounds for the plot area. This functionality is required in the new version.

Overview

Add the ability for the user to specify an X range and a Y range. The plot area should only update when the user clicks a submit button.

Acceptance Criteria

  • User can input a X range
  • User can input a Y range
  • The ranges are displayed using a halogen component and are NOT just appended to the main component.

Closing Notes

Overview of changes can be found in PR #37

image

Mouse scroll should not zoom outside canvas

Details:

Hours Spent: 1

Background

As the app's web page sometimes does not fit the view, users will attempt to scroll the page to see the parts not visible. Page scrolling is often habitually done using the mouse scroll wheel.

Overview

Currently, the mouse scroll invokes canvas zoom anywhere on the page. It would be more desirable if the mouse scroll outside the canvas would scroll the page as usual instead of zooming the canvas.

Acceptance Criteria

  • Mouse scroll on canvas zooms the canvas as it does now.
  • Mouse scroll outside the canvas has its usual default behaviour, ie scroll the page in the usual default browser settings.

Closing Notes

Overview of changes can be found in PR #96

User defined variables

Details:

Hours Spent: 0

Background

In the previous iteration of this application, the user could write expressions containing variables other than x. This can be completed alongside #38

Overview

Add the ability for the user input a pair of boundary values for a given variable then plot based on the values and the given variable.

Acceptance Criteria

TBD

Closing Notes

Overview of changes can be found in PR PR ID HERE

Add bounds reset button

Details:

Hours Spent: 1

Background

When the user zooms out/in or pans too far it is annoying to have to pan/zoom all the way back to the origin.

Overview

Add a button that will reset the XY bounds back to the default initial value when pressed.

Acceptance Criteria

  • Added button

Closing Notes

Overview of changes can be found in PR #43

When pressed this button functions as expected.

image

Add missing Approx functions

Details:

Hours Spent: 0
Duplicate of #8

Background

The Approx type does not have support for the trigonometry functions sin, cos and tan. In addition to this, there is no support for power computation and log.

Overview

Add the implementation of the following functions for Approx

  • log
  • sin
  • sqrt
  • cos
  • tan
  • pow
  • e^

Acceptance Criteria

  • All the functions in the overview are implemented.

Closing Notes

Overview of changes can be found in PR PR ID HERE

Add Approx constants and rounding

Details:

Hours Spent: 0

Background

Part of epic #8.

Overview

Add tools to create Approx objects for integer and rational numbers, rounded with a given accuracy.

Acceptance Criteria

  • function for rounding an Approx to a given mBound (in PR #21)
  • function for comparing two `Approx' for set inclusion
  • functions for approximating a given integer (or big integer) as an Approx
  • function for approximating a rational number as an Approx

Closing Notes

Overview of changes can be found in PR #45

Add the plot for 1/(1+100*x^2)

Details:

Hours Spent: 6

Background

One of the requirements for M1 is to plot y = 1/(1+100*x^2).

Overview

Add a button to the user interface that will plot the function y = 1/(1+100*x^2). This should be plotted using a simple line. This will require adding a new draw command that will draw a line between two points.

Acceptance Criteria

  • The user can press a button and the function y = 1/(1+100*x^2) is plotted

Closing Notes

Overview of changes can be found in PR #16

The function appears when the user presses the button. I added unit tests to assert that the expected values were given and they were too an accuracy of ±0.00000000000000001 which is an accuracy that cannot be seen within the test domain.
image

Redraw robust enclosure only when pan is finished

Details:

Hours Spent: 4

Background

Robust enclosure drawing could be computation-intensive and is handled asynchronously in batches via the JobQueue.
Currently, while dragging or zooming, the robust enclosure computation is scheduled continually. It would be sufficient to draw the rough enclosure during this process.

Overview

Reduce the amount of enclosure computation by delaying it after a pan or zoom is finished.

Acceptance Criteria

  • While zooming or panning, the rough plot is being redrawn but no enclosure is being computed or plotted.
  • Enclosure computation is scheduled when mouse panning is finished or 0.5s after last mouse scroll event.

Closing Notes

Overview of changes can be found in PR #71

Add Approx field operations

Details:

Hours Spent: 0

Background

This is part of epic #8. Field operations (+, -, *, /) are essential for computing function plots.

Overview

Port the operations from relevant parts of CDAR to form a Field type class instance.

Acceptance Criteria

  • instance Semiring Approx
  • instance Ring Approx
  • instance EuclideanRing Approx
  • instance Field Approx

Closing Notes

Overview of changes can be found in PR #45

Set up canvas

Details:

Hours Spent: 13

Background

The canvas is how the user will view the plot. This canvas needs to be able to display all the features that are found in CanvasPlotter.hs

Overview

The canvas should be embedded in the halogen view. There should be a button added to the view that can be made to call any of the features like draw polygon. This is simply a proof of concept and hence the appearance of these features can be refactored later.

Acceptance Criteria

  • There is a UI button that will draw a simple polygon on the canvas

Closing Notes

Overview of changes can be found in #11

It should be noted that there is currently no support for stopping plot computation in the middle of its execution as this requires a unique way to handle doing large computations.

Custom function input

Details:

Hours Spent: 5

Background

The previous version of the application would allow the user to input a custom equation that was parsed and executed. This functionality is required in the new application.

Overview

Add simple user interface controls that allow the user to input a function into a text box and then press a 'plot' button to plot the expression on the canvas. This should be completed after #22

Acceptance Criteria

  • The user can input an expression that is parsed
  • When the user inputs an invalid expression an error message is displayed

Closing Notes

Overview of changes can be found in PR #29

image

The expression input functions as expected in that when a user inputs a valid expression it is displayed on the canvas. At the moment the plot only works for expressions where x is the only variable. Added #30 to address this.

MicrosoftTeams-image

When the user inputs a variable that is unknown or there is a parsing error it is displayed under the input box. The way that expressions are validated is that first they are parsed. Then they are evaluated with a test number (currently zero) to check if they can be evaluated. It should be noted that this is performed when the user presses plot, not when the value in the text box is changed.

Add interconnected parallelogram plot

Details:

Hours Spent: 5

Background

The plot is currently a series of boxes. While this does describe the bounds it does not represent the shape.

Overview

Update the robust plot so that the boxes are drawn as a series of interconnected parallelogram similar to the original version.

image

Algorithm

On each segment x = [xL, xU]

  1. let xM = (xL+xU)/2
  2. let w = (xU-xL)
  3. compute enclosure of f(xM)
  4. compute enclosure of f’(x)
  5. compute enclosure of f(xU) as
  6. lower bound = f(xM)L + (w/2)*f’(x)L
  7. upper bound = f(xM)U + (w/2)*f’(x)U
  8. compute enclosure of f(xL) as
  9. lower bound = f(xM)L - (w/2)*f’(x)U
  10. upper bound = f(xM)U - (w/2)*f’(x)L
  11. form a parallelogram using the bounds on f(xL) and f(xU)

Acceptance Criteria

  • The plot is drawn as a series of interconnected parallelograms

Closing Notes

Overview of changes can be found in PR #75

image

Robust Arithmetic

Details:

Hours Spent: 0

Background

Enclosure arithmetic is needed to compute enclosures of functions given by formulas.

Overview

Port relevant parts of module Approx from Haskell CDAR including relevant tests.

Acceptance Criteria

  • constants can be defined and printed (#9 )
  • field operations (+,-,*,/), are supported (#20 )
  • sqrt is supported
  • sine, cosine and pi are supported (#93)
  • exp, log and e are supported (#98)

Closing Notes

Overview of changes can be found in PR PR ID HERE

Remove Job Batching

Details:

Hours Spent: 0.5

Background

Child issue of #76

The current incarnation of plot batching is fixed and does not adapt to the plot being drawn.

Overview

Remove the job batching from the user interface and make it so that the plot command is computed in a single batch. The infrastructure for handling batched jobs will be useful in the future however its next version will likely come from some heuristic rather than simply separating the domain into a fixed number of subdomains.

Acceptance Criteria

  • From the user perspective, there is no batching
  • In the backend the batchCount is always set to 1

Closing Notes

Overview of changes can be found in PR #80

Support abs, min, max in expressions + automatic differentiation

Details:

Hours Spent: 0

Background

The plotter should support also functions such as abs, min and max. These operators lead to functions that are not differentiable everywhere but differentiable almost everywhere. It is not feasible to represent the derivative of these functions in our expression language.

Overview

  • Introduce operators abs, min ans max into the expression language.
  • Replace differentiation of expression with an evaluator that returns a value of an expression together with the (interval) derivative and second derivative (or its rough approximation or interval enclosure).

Wikipedia

Acceptance Criteria

  • The plotter accepts input such as "abs(x)" or "max(x,-x)".
  • The plotter plots both rough graphs and enclosures of such functions.
  • The quality of smooth plots is not decreased.

Closing Notes

Overview of changes can be found in PR #113

Draw enclosures

Overview

Try and compute the function on a fine grid (eventually automatic). User can define initial segmentation aka the number of segments (Initially this fixed and user-defined in UI, will be adaptive later). Box only in an even partition. Draw boxes in atomic batches (to fine and the boxes are invisible). Initially, the number of batches is a fixed parameter in UI. Pause button so that the computation. Pan/Zoom will clear enclosure plot. For unsupported operations unsafeThrow "Unsupported operation".

Issues

Acceptance Criteria

This issue is complete when all its child issues are complete.

Add batch size user input

Details:

Hours Spent: 1

Background

Member of epic #46

Overview

The user should be able to specify the number of batches that the robust plot is drawn in.

Acceptance Criteria

  • There is a text box where the user can input the number of batches that the robust plot should be drawn in.
  • There should be an error preventing the number of batches being less than 1

Closing Notes

Overview of changes can be found in PR #70

Check/fix formatting "0.2:~"

Details:

Hours Spent: 0

Background

showA $ Approx 9 (big 102) (big 1) (-9)
"0.2:~"

Overview

Check whether this formatting is intended. If yes, document what it means. If not, fix it.

Acceptance Criteria

  • Test for formatting this number

Closing Notes

Overview of changes can be found in PR PR ID HERE

Automatic batching

Details:

Hours Spent: 4

Background

Child issue of #76
Dependent on #78

The plot computation needs to be batched into a series of jobs.

Overview

Break the collection of segments into a user-definable number of batches. Each batch will have a fixed number of segments of varying widths.

Acceptance Criteria

  • The plot is automatically batched where each batch has a fixed number of segments.

Closing Notes

Overview of changes can be found in PR #80

Improved axis

Details:

Hours Spent: 1

Background

Currently, when the user moves the canvas they very quickly lose track of where the origin of the plot is.

Overview

Add a solid black line to represent the origin of both the x-axis and the y-axis.

Acceptance Criteria

  • There is a solid line on the x-axis
  • There is a solid line on the y-axis

Closing Notes

Overview of changes can be found in #33
image

Set up the repository

Details:

Hours Spent: 4

Background

The repository is set up but there are no unit tests and the process of setting up the repo is not well defined.

Overview

The aim of this issue is to set up the build so that the project can be initially installed with a single command. In addition to this, there should be at least one example unit test. The package.json should also contain the basic project information including the licence and title.

Acceptance Criteria

  • Project can be installed from scratch using npm run install
  • 1 example unit test case exists
  • Unit tests can be executed using npm run test
  • Meta information for the project exists in package.json
  • Add issue template for new issues
  • Update the README.md to include the install steps for new developers

Closing Notes

Ran into issue where an error occurs when the spago build is executed (see spago#635). This means that the CI pipeline fails. Hence is have commented out the line that runs the tests in the CI pipeline.

Overview of changes can be found in PR #3

Multiple functions labels

Details:

Hours Spent: 4

Background

Dependent on the completion of #31.

Overview

Add labels to the functions that are plotted in a way that they are all visible to the user and clearly denote which line they are assigned to.

Acceptance Criteria

  • When plotting a line a label will appear over the line. This label should appear in a box that is readable regardless of zoom

Closing Notes

Overview of changes can be found in PR #43

image

Add mouse zooming to canvas

Details:

Hours Spent: 2

Background

The user should be able to zoom in and out using the scroll wheel on the mouse.

Overview

Update the canvas component to listen for the user's mouse scrolling when the user hovers over it.

Acceptance Criteria

  • When the user pushes the mouse wheel forward the plot should be zoomed in by 10%
  • When the user pushes the mouse wheel backwards the plot should be zoomed out by 10%

Closing Notes

Overview of changes can be found in PR #33

I replaced the scroll wheel event on the web page with an event subscriber that will trigger the Zoom action based on the change in the scroll wheel Y-axis value.

Add mouse panning to canvas

Details:

Hours Spent: 2

Background

The user should be able to easily pan by dragging with the mouse.

Overview

Update the canvas so that the user can click and drag the plot.

Acceptance Criteria

  • When the user clicks in their mouse and holds, moving the mouse left click causes the plot to follow the cursor.
  • When the user has dragged the plot, releasing the mouse click causes the plot to stop following the cursor.

Closing Notes

Overview of changes can be found in PR #33

Adaptive segmentation

Details:

Hours Spent: 8

Background

Child issue of #76
Dependent on #77

Currently, the segmentation for the robust plot is even-spaced and user-defined. In the future, the user will simply specify a target accuracy level.

Overview

Update the robust plot so that the segmentation is done based on a rough evaluation of the second derivative of the expression.

Main ideas of the algorithm:

  • Recursively bisect the domain of x and collect the list of bisected segments.
  • For each segment, decide whether to bisect further as follows:
    • Always bisect if not at a minimum depth (eg 5)
    • Never bisect if depth is above a maximum depth (eg 15)
    • Roughly evaluate the second derivative at two points in the segment: a1 = f''(m1), a2 = f''(m2)
    • If |a1-a2| > the accuracy tolerance, bisect. (We reckon we do not know the second derivative reliably enough.)
    • Let a = (a1+a2)/2.
    • Roughly evaluate the first derivative: b = f'(m) where m is the centre of the segment.
    • Approximate the function with the form ax^2 + bx over a segment centred at 0 of radius w (where w is half the segment width)
    • Measure the "accuracy" of the parallelogram enclosing this form:
      • Its y-axis aligned height is hx = |a|*w^2.
      • Its perpendicular height is hp = |a|*w^2/(sqrt(b^2+1)) which can be approximated by |a|*w^2/(max(|b|,1))
      • Accuracy definition to use: h = if |b| > 1 then |a/b|*w^2 else |a|/w^2
    • If h > accuracy target, split.

Acceptance Criteria

  • Implement the algorithm above segmenting based on h

Closing Notes

Overview of changes can be found in PR #80

Add batch operation support

Details:

Hours Spent: 22

Background

Member of epic #46. Very complex functions require a high amount of precision and may be very slow to compute. Hence the computation should be broken down into batches so that the user can see the view update with each batch that is processed.

Overview

Add a new type BatchOperation that defines a plot region to compute which is bounded in x. Then add an array of these operations to the state. When the user clicks plot the expression should be broken into these batch commands. These commands are then sequentially executed. Inbetween each execution the view should be updated.

image

Dev Note
The sequential part should be done by having a computation action. This action should be triggered when new batch operations are added. It should take the first batch command and execute it asynchronously. When it is complete the view state should be updated and that batch command should be removed. Once the state is updated the action should be triggered again.

Acceptance Criteria

  • Expressions are computed as batches
  • There is evidence that it performs as expected with an expression that is slow to compute (This can be done by delaying the expression computation).

Closing Notes

Overview of changes can be found in PR #61

Re-enable plot line labelling

Details:

Hours Spent: 7

Background

The labelling was disabled as part of #61 and needs to be re-implemented.

Overview

Add plot labelling so that it conforms to the criteria defined in #32

Acceptance Criteria

  • Labels are displayed on the plot

Closing Notes

Overview of changes can be found in PR #100

Add panning

Details:

Hours Spent: 3

Background

The previous version of this application had support for the user to pan up, down, left and right on the plot. This functionality is required in this version also.

Overview

Panning is a simple operation from the user perspective. However, from our perspective, we need to account for the user panning to regions of the plot that have not been drawn prior to the panning.

For this issue, we need to add a button for panning in each of the directions on the plane (up, down, left and right). When clicked each of these operations will move the plot and in the respective direction. The panning operation should have access to the previous drawing commands and be able to translate each of them such that the operations are drawn in the correct place.

Acceptance Criteria

  • The user can press the 'pan up' to move the plot 10% of its range downward.
  • The user can press the 'pan down' to move the plot 10% of its range upward.
  • The user can press the 'pan left' to move the plot 10% of its range right.
  • The user can press the 'pan right' to move the plot 10% of its range left.

Closing Notes

Overview of changes can be found in PR #17

Currently, the panning is extremely simple. It just redraws the plot with the new bounds each time the button is pressed.
image

Fix expression printing

Details:

Hours Spent: 1

Background

Over the course of the application how the expressions are printed was defined.

Overview

Update the printing for the ExpressionUnary data constructor for Expression so that variables and literals nested within functions like sin and log are wrapped by brackets.

Examples:

  • ExpressionUnary Sine (ExpressionVariable "x") should be printed as sin(x)
  • ExpressionUnary Cosine (ExpressionVariable "x") should be printed as cos(x)
  • ExpressionUnary Tan (ExpressionVariable "x") should be printed as tan(x)
  • ExpressionUnary Log (ExpressionVariable "x") should be printed as log(x)
  • ExpressionUnary Sqrt (ExpressionVariable "x") should be printed as sqrt(x)
  • ExpressionUnary Exp (ExpressionVariable "x") should be printed as e^x
  • ExpressionUnary Exp (ExpressionLiteral 4) should be printed as e^4

Acceptance Criteria

  • There is a test for each example asserting that the expression is outputted correctly

Closing Notes

Overview of changes can be found in PR #75

I did also assume that:

  • ExpressionUnary Neg (ExpressionVariable "x") should be printed as -x
  • ExpressionUnary Neg (ExpressionLiteral 4) should be printed as -4

Accurate parse error reporting

Details:

Hours Spent: 1

Background

Created due to error checking issues that arose during the initial development of the user inputted expressions in #22

Overview

When the user inputs an incorrect expression the expression parser should output an error message appropriate to the error that was made.

Acceptance Criteria

  • When the user inputs an invalid function name it is returned as the error

Closing Notes

Overview of changes can be found in PR #27

Refactor Expression to use Rational numbers

Details:

Hours Spent: 10

Background

See closing notes #22

Overview

Refactor all the uses of Number in the expressions to use Rational instead

Acceptance Criteria

  • Parser for numeric literals as Rational
  • Update Expression type definition
  • Update evaluator (REMOVED due to performance concerns)

Closing Notes

Overview of changes can be found in PR #44

I had to remove the ability to simplify constant power expressions as there is no implementation of the pow function for Rational.

Parsing literals such as 0.001

Details:

Hours Spent: 2

Background

The expression parser seems to have a problem with some literals.

Overview

After entering the expression "0.001" into the plotter, it is treated as "0.1". The same happens for "0.01" - it is also treated as "0.1".

Acceptance Criteria

  • When entering the constant function "0.01", it is plotted at the correct height.

Investigation

I added some tests to check the input of these family of values and noticed that all the decimal inputs are broken.
image

The issue was being caused by how we were handling the denominator of the ratio values. Previously the assumption was that there was no simplification of the ratio values. For example, 10/4 was assumed to be stored as 10/4 when in reality it was simplified to 5/2. The rational parsing assumed that the denominator would always be a multiple of 10. This was not the case.

This issue was also present in the Components.BoundsInput as there is duplicate code from the Expression.Parser there.

Closing Notes

Overview of changes can be found in PR #69

image

Update CI pipeline to test code changes

Details:

Hours Spent: 0.5

Background

Initially added in #2, the CI pipeline was set up to run upon each pull request of the project. The only problem was that the spago version '0.15.2' has a bug where an error occurs during the build. This doesn't impact local builds but the CI pipeline is not able to be run them as errors in a CI pipeline environment will cause the pipeline to fail.

Overview

This issue has been fixed in the current master branch build of spago. When version 0.15.3 is released this issue is to update the CI pipeline to test the code.

Acceptance Criteria

  • CI pipeline tests the code

Closing Notes

Overview of changes can be found in PR #57

Custom function backend

Details:

Hours Spent: 17

Background

Broken out from #19

Overview

Port over the expression module from the previous version of the application (available here).

Acceptance Criteria

  • Unit tests exist that test the expression y = 1 / (1 + (100 * x^2)) and ensures it is parsed correctly
  • Unit tests exist that test the expression y = sin(x) and ensures it is parsed correctly

Closing Notes

Overview of changes can be found in PR #23

Integrated the purescript-parsing library into the project. This allows the simple parsing of expressions into the Expression type. The Expression type defines 4 different constructors.

  • ExpressionVariable which wraps a variable name
  • ExpressionLiteral which wraps a literal number value
  • ExpressionUnaryOperation which wraps a unary operation and the expression that operation is performed on.
  • ExpressionBinaryOperation which wraps a binary operation and the two expressions that operation is performed on.

Something to note about this is that the constant values like pi and e have to be defined as variables when the expression is evaluated.

One issue that was encountered while working on this issue is a problem with the parser. Basically, when the parser parses long literal numbers there is a loss in precision. This is why issue #24 was added. This can be attributed to the token.naturalOrFloat parser found in Expression.Parser for literal values.

Multiple function plotting

Details:

Hours Spent: 5

Background

The previous version of the application had the ability for the user to define many functions on the canvas at once.

Overview

Add an option for the user to input multiple functions.

Acceptance Criteria

  • There should be a button that creates another expression input component
  • When the user clicks 'plot' on that expression input is plotted

Closing Notes

Overview of changes can be found in PR #37

image

I tested the performance of panning and zooming with 4 lines and it seems to be still un noticeably slowed.

Expression does not plot: (1-(x/6)*(1-(x/20)))

Details:

Hours Spent: 2

Background

Some expressions lead to a blank plot:
image

Overview

On inputting the expression (1-(x/6)(1-(x/20))) the plot is entirely empty.
Various minor simplifications of this expression do plot as expected, eg
((x/6)
(1-(x/20))) and (1-(x)*(1-(x/20))).

Acceptance Criteria

  • Inputting the expression (1-(x/6)*(1-(x/20))) gives a plot similar to:
    image

Closing Notes

Overview of changes can be found in PR #72

The bug was caused by the fact that the list of extracted variables was not passed down to the next recursive call of orderDepencenciesWithMap. This was amended by simply appending the extracted and newExtractedValueArray together.

image
The plot appears as expected.

Add expression evaluation using Approx

Details:

Hours Spent: 3.5

Background

Member of epic #46. Approx will be used to ensure that the calculations for the graph equations are robust. This means that the values of equations are given as an area instead of a discrete value.

Overview

Add a new evaluation function that will evaluate an expression to an Approx. This function will need to convert the Rational types into Approx. These should be at a precision of 50 in this initial iteration. This functionality should be covered by exhaustive unit tests to ensure that it performs as expected.

This issue requires the completion of #54 but for the time being, it can be completed by simplifying throwing an error for each of the functions if an expression uses them.

Acceptance Criteria

  • There is a new evaluate function that uses Approx variable values and results in an Expect Approx
  • This evaluate function is covered by unit tests

Closing Notes

Overview of changes can be found in PR #57

Draw lines as enclosures

Details:

Hours Spent: 10

Background

Member of epic #46. Currently, the rough evaluation plot is used. However, a robust plot is required.

Overview

Update the drawing pipeline so that once the rough plot has been drawn the line is drawn as a series enclosures. The Approx type results in an upper and lower bound. So for the x range, each point will have an upper and lower bound. Then this corresponds to a y point with an upper and lower bound.
x = xLower ... xUpper
y = yLower ... yUpper

a = (xLower, yUpper)
b = (xUpper, yUpper)
c = (xUpper, yLower)
d = (xLower, yLower)

Draw the enclosure as a polygon with points in the following order.
a -> b -> c -> d -> a

In theory, the draw time should be 3 times longer than the rough plot, however, the computation time difference is unknown at this point. The drawing of these robust plots should be async from the rough plot. This means that when the rough plot is complete, it should update the state and trigger a new action. This action should compute the robust plot (after an artificial delay). Once this action is complete it should trigger a new action. This final action will check to see if any other plots have been triggered since the async computation has started. If any have then the robust plot commands should be ignored. Later robust plots that are to be ignored will be cancelled however the this will do for M3.

Acceptance Criteria

  • The plot is drawn as a series of enclosures
  • When the robust plot is drawn the rough plot is removed
  • The robust plots are calculated async after the rough plot

Closing Notes

Overview of changes can be found in PR #59

image

After an artificial delay of 2 seconds, the robust plot will appear.

Add line segmentation user input

Details:

Hours Spent: 1

Background

Member of epic #46

Overview

The user should be able to specify the number of segments that the robust plot is displayed in.

Acceptance Criteria

  • Add a text input where the user can specify the number of segments the line should be broken into.

Closing Notes

Overview of changes can be found in PR #70

Handle evaluation errors in plot

Details:

Hours Spent: 1

Background

When the robust and rough plots are drawn, if there is an evaluation error, zero is currently outputted. This insufficient as some functions like y=sqrt(x) is undefined when x < 0.

Overview

Update the plotting module Plot.RobustPlot and Plot.RoughPlot so that when an evaluation error is encountered nothing is plotted at that position.

Acceptance Criteria

  • For the rough plot, the line stops at that point before an evaluation error.
  • For the rough plot, the line starts at that point after an evaluation error.
  • For the rough plot, nothing is plotted if the error occurred at the current and previous points.
  • For the robust plot, if and an error occurs at a point that enclosure is not drawn.

Closing Notes

Overview of changes can be found in PR #72

image

Plotting level control

Details:

Hours Spent: 7

Background

Overview

Users need to be able to switch individual functions on/off and control whether they want to see a rough plot only or a robust enclosure for each function. This is needed to allow the user to focus temporarily on a subset of functions.and/or speed up the plotting of some functions.

Acceptance Criteria

  • There is a three-value control next to each function expression input box labelled "off" "rough" "robust" (or similar).
  • The plot responds to a change in the control quickly (unless it is stuck in a single difficult enclosure comptuation batch).

Closing Notes

Overview of changes can be found in PR #72

image

Pause computation

Details:

Hours Spent: 0
Completed as part of #61

Background

Overview

Update the way that the plots are computed so that they can be stopped mid computation. This should be evaluated by adding an artificial delay to the computation and making the computation occur in a series of steps.

Acceptance Criteria

TBD

Closing Notes

Overview of changes can be found in PR PR ID HERE

Loss of plot smoothness

Details:

Hours Spent: 3

Background

This is a regression in terms of visual performance.

Overview

With the equation x*sin(1/(100*x^2))

In #40
image

In #47
image

Acceptance Criteria

  • The graph line appears, in the master build, visually identical to the version at #40

Investigation

After investigation, this was not caused by the change to rational as the graph still appears correctly as of #44
image

The cause of this issue was the changes made as part of #47 as the graph still appeared correctly in #45
image

Closing Notes

This issue was caused by missing cases in the removeSubExpressions in Expression.SubExpression. Basically, when removing sub-expressions the function would not account for binary operations, unary operations and recurse into the expressions in the expression variable map.

image

Overview of changes can be found in PR #57

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.