phetsims / curve-fitting

"Curve Fitting" is an educational simulation in HTML5, by PhET Interactive Simulations.
GNU General Public License v3.0
6 stars 3 forks source link

CT: x needs to be a number #113

Closed KatieWoe closed 5 years ago

KatieWoe commented 5 years ago
curve-fitting : fuzz : require.js-canvas : run
Uncaught Error: Assertion failed: x needs to be a number
Error: Assertion failed: x needs to be a number
    at window.assertions.assertFunction (https://bayes.colorado.edu/continuous-testing/snapshot-1540180835952/assert/js/assert.js:22:13)
    at new Vector2 (https://bayes.colorado.edu/continuous-testing/snapshot-1540180835952/dot/js/Vector2.js?bust=1540204182337:36:15)
    at v (https://bayes.colorado.edu/continuous-testing/snapshot-1540180835952/kite/js/Shape.js?bust=1540204182337:48:31)
    at CurveShape.cubicCurveTo (https://bayes.colorado.edu/continuous-testing/snapshot-1540180835952/kite/js/Shape.js?bust=1540204182337:427:72)
    at CurveShape.addCubic (https://bayes.colorado.edu/continuous-testing/snapshot-1540180835952/curve-fitting/js/curve-fitting/model/CurveShape.js?bust=1540204182337:144:38)
    at CurveShape.addSegments (https://bayes.colorado.edu/continuous-testing/snapshot-1540180835952/curve-fitting/js/curve-fitting/model/CurveShape.js?bust=1540204182337:156:9)
    at new CurveShape (https://bayes.colorado.edu/continuous-testing/snapshot-1540180835952/curve-fitting/js/curve-fitting/model/CurveShape.js?bust=1540204182337:48:14)
    at Curve.getShape (https://bayes.colorado.edu/continuous-testing/snapshot-1540180835952/curve-fitting/js/curve-fitting/model/Curve.js?bust=1540204182337:108:14)
    at Emitter.updateCurve (https://bayes.colorado.edu/continuous-testing/snapshot-1540180835952/curve-fitting/js/curve-fitting/view/CurveNode.js?bust=1540204182337:46:72)
    at Emitter.emit (https://bayes.colorado.edu/continuous-testing/snapshot-1540180835952/axon/js/Emitter.js?bust=1540204182337:187:53)
id: Bayes Chrome
Approximately 10/21/2018, 10:00:35 PM
curve-fitting : xss-fuzz : run
Uncaught Error: Assertion failed: x needs to be a number
Error: Assertion failed: x needs to be a number
    at window.assertions.assertFunction (https://bayes.colorado.edu/continuous-testing/snapshot-1540180835952/assert/js/assert.js:22:13)
    at new Vector2 (https://bayes.colorado.edu/continuous-testing/snapshot-1540180835952/dot/js/Vector2.js?bust=1540220027060:36:15)
    at v (https://bayes.colorado.edu/continuous-testing/snapshot-1540180835952/kite/js/Shape.js?bust=1540220027060:48:31)
    at CurveShape.cubicCurveTo (https://bayes.colorado.edu/continuous-testing/snapshot-1540180835952/kite/js/Shape.js?bust=1540220027060:427:72)
    at CurveShape.addCubic (https://bayes.colorado.edu/continuous-testing/snapshot-1540180835952/curve-fitting/js/curve-fitting/model/CurveShape.js?bust=1540220027060:144:38)
    at CurveShape.addSegments (https://bayes.colorado.edu/continuous-testing/snapshot-1540180835952/curve-fitting/js/curve-fitting/model/CurveShape.js?bust=1540220027060:156:9)
    at new CurveShape (https://bayes.colorado.edu/continuous-testing/snapshot-1540180835952/curve-fitting/js/curve-fitting/model/CurveShape.js?bust=1540220027060:48:14)
    at Curve.getShape (https://bayes.colorado.edu/continuous-testing/snapshot-1540180835952/curve-fitting/js/curve-fitting/model/Curve.js?bust=1540220027060:108:14)
    at Emitter.updateCurve (https://bayes.colorado.edu/continuous-testing/snapshot-1540180835952/curve-fitting/js/curve-fitting/view/CurveNode.js?bust=1540220027060:46:72)
    at Emitter.emit (https://bayes.colorado.edu/continuous-testing/snapshot-1540180835952/axon/js/Emitter.js?bust=1540220027060:187:53)
id: Bayes Chrome
Approximately 10/21/2018, 10:00:35 PM
KatieWoe commented 5 years ago
curve-fitting : fuzz : require.js-canvas : run
Uncaught Error: Assertion failed: x needs to be a number
Error: Assertion failed: x needs to be a number
    at window.assertions.assertFunction (https://bayes.colorado.edu/continuous-testing/snapshot-1546923822816/assert/js/assert.js:22:13)
    at new Vector2 (https://bayes.colorado.edu/continuous-testing/snapshot-1546923822816/dot/js/Vector2.js?bust=1546931572747:36:15)
    at v (https://bayes.colorado.edu/continuous-testing/snapshot-1546923822816/kite/js/Shape.js?bust=1546931572747:48:31)
    at CurveShape.quadraticCurveTo (https://bayes.colorado.edu/continuous-testing/snapshot-1546923822816/kite/js/Shape.js?bust=1546931572747:328:57)
    at CurveShape.addQuadratic (https://bayes.colorado.edu/continuous-testing/snapshot-1546923822816/curve-fitting/js/curve-fitting/model/CurveShape.js?bust=1546931572747:119:38)
    at CurveShape.addSegments (https://bayes.colorado.edu/continuous-testing/snapshot-1546923822816/curve-fitting/js/curve-fitting/model/CurveShape.js?bust=1546931572747:156:9)
    at new CurveShape (https://bayes.colorado.edu/continuous-testing/snapshot-1546923822816/curve-fitting/js/curve-fitting/model/CurveShape.js?bust=1546931572747:53:14)
    at Curve.getShape (https://bayes.colorado.edu/continuous-testing/snapshot-1546923822816/curve-fitting/js/curve-fitting/model/Curve.js?bust=1546931572747:108:14)
    at Emitter.updateCurve (https://bayes.colorado.edu/continuous-testing/snapshot-1546923822816/curve-fitting/js/curve-fitting/view/CurveNode.js?bust=1546931572747:46:72)
    at Emitter.emit (https://bayes.colorado.edu/continuous-testing/snapshot-1546923822816/axon/js/Emitter.js?bust=1546931572747:218:55)
id: Bayes Chrome
Approximately 1/7/2019, 10:03:42 PM
KatieWoe commented 5 years ago

May be similar

curve-fitting : fuzz : require.js : run
Query: brand=phet&ea&fuzz&memoryLimit=1000
Uncaught Error: Assertion failed: x must be a finite number: null
Error: Assertion failed: x must be a finite number: null
    at window.assertions.assertFunction (https://bayes.colorado.edu/continuous-testing/snapshot-1550029257249/assert/js/assert.js:22:13)
    at CurveShape.quadraticCurveTo (https://bayes.colorado.edu/continuous-testing/snapshot-1550029257249/kite/js/Shape.js?bust=1550049494108:340:17)
    at CurveShape.addQuadratic (https://bayes.colorado.edu/continuous-testing/snapshot-1550029257249/curve-fitting/js/curve-fitting/model/CurveShape.js?bust=1550049494108:119:38)
    at CurveShape.addSegments (https://bayes.colorado.edu/continuous-testing/snapshot-1550029257249/curve-fitting/js/curve-fitting/model/CurveShape.js?bust=1550049494108:156:9)
    at new CurveShape (https://bayes.colorado.edu/continuous-testing/snapshot-1550029257249/curve-fitting/js/curve-fitting/model/CurveShape.js?bust=1550049494108:53:14)
    at Curve.getShape (https://bayes.colorado.edu/continuous-testing/snapshot-1550029257249/curve-fitting/js/curve-fitting/model/Curve.js?bust=1550049494108:108:14)
    at updateCurve (https://bayes.colorado.edu/continuous-testing/snapshot-1550029257249/curve-fitting/js/curve-fitting/view/CurveNode.js?bust=1550049494108:45:72)
    at Emitter.emit (https://bayes.colorado.edu/continuous-testing/snapshot-1550029257249/axon/js/Emitter.js?bust=1550049494108:251:55)
    at Curve.updateFit (https://bayes.colorado.edu/continuous-testing/snapshot-1550029257249/curve-fitting/js/curve-fitting/model/Curve.js?bust=1550049494108:141:31)
    at Emitter.emit (https://bayes.colorado.edu/continuous-testing/snapshot-1550029257249/axon/js/Emitter.js?bust=1550049494108:251:55)
id: Bayes Chrome
Approximately 2/12/2019, 8:40:57 PM
curve-fitting : fuzz : require.js-canvas : run
Query: brand=phet&ea&fuzz&rootRenderer=canvas&memoryLimit=1000
Uncaught Error: Assertion failed: x must be a finite number: null
Error: Assertion failed: x must be a finite number: null
    at window.assertions.assertFunction (https://bayes.colorado.edu/continuous-testing/snapshot-1550029257249/assert/js/assert.js:22:13)
    at CurveShape.quadraticCurveTo (https://bayes.colorado.edu/continuous-testing/snapshot-1550029257249/kite/js/Shape.js?bust=1550069907414:340:17)
    at CurveShape.addQuadratic (https://bayes.colorado.edu/continuous-testing/snapshot-1550029257249/curve-fitting/js/curve-fitting/model/CurveShape.js?bust=1550069907414:119:38)
    at CurveShape.addSegments (https://bayes.colorado.edu/continuous-testing/snapshot-1550029257249/curve-fitting/js/curve-fitting/model/CurveShape.js?bust=1550069907414:156:9)
    at new CurveShape (https://bayes.colorado.edu/continuous-testing/snapshot-1550029257249/curve-fitting/js/curve-fitting/model/CurveShape.js?bust=1550069907414:53:14)
    at Curve.getShape (https://bayes.colorado.edu/continuous-testing/snapshot-1550029257249/curve-fitting/js/curve-fitting/model/Curve.js?bust=1550069907414:108:14)
    at updateCurve (https://bayes.colorado.edu/continuous-testing/snapshot-1550029257249/curve-fitting/js/curve-fitting/view/CurveNode.js?bust=1550069907414:45:72)
    at Emitter.emit (https://bayes.colorado.edu/continuous-testing/snapshot-1550029257249/axon/js/Emitter.js?bust=1550069907414:251:55)
    at Curve.updateFit (https://bayes.colorado.edu/continuous-testing/snapshot-1550029257249/curve-fitting/js/curve-fitting/model/Curve.js?bust=1550069907414:141:31)
    at Emitter.emit (https://bayes.colorado.edu/continuous-testing/snapshot-1550029257249/axon/js/Emitter.js?bust=1550069907414:251:55)
id: Bayes Chrome
Approximately 2/12/2019, 8:40:57 PM
KatieWoe commented 5 years ago

May have added to the error

curve-fitting : fuzz : require.js-canvas : run
Query: brand=phet&ea&fuzz&rootRenderer=canvas&memoryLimit=1000
Uncaught Error: Assertion failed: x must be a finite number: null
Error: Assertion failed: x must be a finite number: null
    at window.assertions.assertFunction (https://bayes.colorado.edu/continuous-testing/snapshot-1554813891114/assert/js/assert.js:22:13)
    at CurveShape.cubicCurveTo (https://bayes.colorado.edu/continuous-testing/snapshot-1554813891114/kite/js/Shape.js?bust=1554819313140:453:17)
    at CurveShape.addCubic (https://bayes.colorado.edu/continuous-testing/snapshot-1554813891114/curve-fitting/js/curve-fitting/model/CurveShape.js?bust=1554819313140:144:38)
    at CurveShape.addSegments (https://bayes.colorado.edu/continuous-testing/snapshot-1554813891114/curve-fitting/js/curve-fitting/model/CurveShape.js?bust=1554819313140:156:9)
    at new CurveShape (https://bayes.colorado.edu/continuous-testing/snapshot-1554813891114/curve-fitting/js/curve-fitting/model/CurveShape.js?bust=1554819313140:48:14)
    at Curve.getShape (https://bayes.colorado.edu/continuous-testing/snapshot-1554813891114/curve-fitting/js/curve-fitting/model/Curve.js?bust=1554819313140:108:14)
    at updateCurve (https://bayes.colorado.edu/continuous-testing/snapshot-1554813891114/curve-fitting/js/curve-fitting/view/CurveNode.js?bust=1554819313140:45:72)
    at Emitter.emit (https://bayes.colorado.edu/continuous-testing/snapshot-1554813891114/axon/js/Emitter.js?bust=1554819313140:280:55)
    at Curve.updateFit (https://bayes.colorado.edu/continuous-testing/snapshot-1554813891114/curve-fitting/js/curve-fitting/model/Curve.js?bust=1554819313140:141:31)
    at Emitter.emit (https://bayes.colorado.edu/continuous-testing/snapshot-1554813891114/axon/js/Emitter.js?bust=1554819313140:280:55)
id: Bayes Chrome
Approximately 4/9/2019, 6:44:51 AM
curve-fitting : fuzz : require.js-canvas : run
Query: brand=phet&ea&fuzz&rootRenderer=canvas&memoryLimit=1000
Uncaught Error: Assertion failed: reentry detected, value=Vector2(20.215888140074593, -7.205773573716844), oldValue=Vector2(-3.8157329772316357, 10.949777176348366)
Error: Assertion failed: reentry detected, value=Vector2(20.215888140074593, -7.205773573716844), oldValue=Vector2(-3.8157329772316357, 10.949777176348366)
    at window.assertions.assertFunction (https://bayes.colorado.edu/continuous-testing/snapshot-1554813891114/assert/js/assert.js:22:13)
    at Vector2Property._notifyListeners (https://bayes.colorado.edu/continuous-testing/snapshot-1554813891114/axon/js/Property.js?bust=1554819313140:244:17)
    at Vector2Property.set (https://bayes.colorado.edu/continuous-testing/snapshot-1554813891114/axon/js/Property.js?bust=1554819313140:160:14)
    at Vector2Property.set value [as value] (https://bayes.colorado.edu/continuous-testing/snapshot-1554813891114/axon/js/Property.js?bust=1554819313140:316:34)
    at translate (https://bayes.colorado.edu/continuous-testing/snapshot-1554813891114/curve-fitting/js/curve-fitting/view/PointNode.js?bust=1554819313140:184:40)
    at first (https://bayes.colorado.edu/continuous-testing/snapshot-1554813891114/scenery/js/input/SimpleDragHandler.js?bust=1554819313140:173:34)
    at Emitter.emit (https://bayes.colorado.edu/continuous-testing/snapshot-1554813891114/axon/js/Emitter.js?bust=1554819313140:280:55)
    at Object.move (https://bayes.colorado.edu/continuous-testing/snapshot-1554813891114/scenery/js/input/SimpleDragHandler.js?bust=1554819313140:303:29)
    at Input.dispatchToListeners (https://bayes.colorado.edu/continuous-testing/snapshot-1554813891114/scenery/js/input/Input.js?bust=1554819313140:1772:27)
    at Input.dispatchEvent (https://bayes.colorado.edu/continuous-testing/snapshot-1554813891114/scenery/js/input/Input.js?bust=1554819313140:1728:12)
id: Bayes Chrome
Approximately 4/9/2019, 6:44:51 AM
pixelzoom commented 5 years ago

Still a problem as of 5/22/19.

veillette commented 5 years ago

image

Step to reproduce: Set curve to BestFit and Cubic; Put four points sharing the same x values and you should be able to trigger the assertions.

veillette commented 5 years ago

The other assertions that is possible to trigger involves the curveShape.quadraticCurveTo.

image

To reproduce set three points sharing the same x values and set the fit to quadratic and BestFIt.

veillette commented 5 years ago

From a pedagogical standpoint, the two cases above are irrelevant and this is a misuse of curve- fitting but given enough time, CT can generate these edge cases scenarios, hence why curve-fitting fails.

At the heart of the failure is that CurveShape attempts to be clever by representing the shape of the curve as a series of quadratic Bezier or cubic Bezier. CurveShape fails at finding the appropriate quadractic/cubic segments. The reason to represent the curve as a series of bezier curve was to address a performance issue on the IPad2. Since one only needs a few bezier segments needed in order to generate a smooth curve it improved the performance on the iPad2, at the cost of significant mathematical complexity.

Previously the curveShape was merely drawn by assembling about 1000 linear segments. This is very easy to implement and failsafe but was slow on the iPad2. If this not longer a consideration, then I suggest that you returned to this approach. In CurveShape, you can enable this method by setting

debug:true

and disable the switch case (line 44 to 58)

If the decision is to represent the CurveShape by a series of linear segments, that would considerably simplify CurveShape and you could cut out 150 lines of codes from CurveShape.

veillette commented 5 years ago

Note that the query parameter snapToGrid=true makes it much easier to trigger the assertions than trying to attempt to put two points on the same x values.

veillette commented 5 years ago

I was able to track down the problem.

Util.solveQuadraticRootsReal(0,0,0) yields null, which is a perfectly reasonable answer since there are no roots for a polynomial of 0x^2+0x+0. A similar issue arises with Util.solveCubicRootsReal(0,0,0,0)

Therefore, when the best fit line solution is 0x^2+0x+0 or 0x^3+0x^2+0x+0, then the findSpecialXCoordinates function in CurveShape will return an array that contains a null value. This null value will generate an exception when attempting to find the cubicCurveTo since the control points will be also null.

A way to deal with the assertion it is to filter out the null values from the array xCoordinates.

Doing so, we obtain a curve that is zero, Curve Fitting screenshot (1)

This should take care of the null value cases and the assertions that were triggered.

However, the question remains : Should we not consider a much simpler brute force approach that would be failsafe (but performant) enough?. I'll log this question in separate issue.

veillette commented 5 years ago

I've ran curveFitting with the query parameters ea&fuzz&snapToGrid=true for 20 minutes, ( snapToGrid=true tremendously increased the likelihood to uncover these edge cases) and it came out clear. So i'll close this issue.