generateFunction("x") new CalcFunctions[randRange(1, CalcFunctions.length - 1)](INNER.f) ( ( OUTER.f[0] === '^' && OUTER.f[1] === 'e' && INNER.f[0] === 'ln' ) || ( OUTER.f[0] === 'ln' && INNER.f[0] === '^' && INNER.f[1] === 'e' ) ) ? 'x' : null
randFromArray( INNER.wrongs ) randFromArray( OUTER.wrongs )
randFromArray( INNER.wrongs ) randFromArray( OUTER.wrongs )
['*', OUTER.ddxF, INNER.ddxF] ( ( OUTER.f[0] === '^' && OUTER.f[1] === 'e' && INNER.f[0] === 'ln' ) || ( OUTER.f[0] === 'ln' && INNER.f[0] === '^' && INNER.f[1] === 'e' ) ) ? [['frac', 'x', 'x'], '1'] : [] DERIVATIVE_SIMPLIFICATIONS.length === 0 ? expr(UNSIMPLIFIED_DERIVATIVE) : expr(DERIVATIVE_SIMPLIFICATIONS[DERIVATIVE_SIMPLIFICATIONS.length - 1]) funcNotation("x")

Let NOTATION.f = OUTER.fText

NOTATION.ddxF = {?}

DERIVATIVE

  • expr(["*", OUTER.ddxF, randFromArray(INNER.wrongs)])
  • expr(["*", randFromArray(OUTER.wrongs), INNER.ddxF])
  • expr(["*", OUTER_WRONG_1, INNER_WRONG_1])
  • expr(["*", OUTER_WRONG_2, INNER_WRONG_1])
  • expr(["+", randFromArray(OUTER.wrongs), randFromArray(INNER.wrongs)])
  • expr(["+", randFromArray(OUTER.wrongs), randFromArray(INNER.wrongs)])
  • expr(OUTER.ddxF)
  • expr(randFromArray(OUTER.wrongs))
  • expr(randFromArray(OUTER.wrongs))
  • 1

NOTATION.ddxF = ( derivative of OUTER.fText with respect to INNER.fText ) \cdot ( derivative of INNER.fText with respect to x)

The derivative of OUTER.fText with respect to INNER.fText is OUTER.ddxFText.

The derivative of INNER.fText with respect to x is INNER.ddxFText.

The derivative at this point is expr(UNSIMPLIFIED_DERIVATIVE), but this expression can be simplified.

expr( i === 0 ? UNSIMPLIFIED_DERIVATIVE : DERIVATIVE_SIMPLIFICATIONS[i - 1] ) can be simplified to expr(newexpr).

So NOTATION.ddxF = DERIVATIVE.

Interestingly, if we simplify the function before we take the derivative, we can reach the answer more quickly: OUTER.fText simplifies to expr(PRE_SIMPLIFICATION), and \frac{d}{dx}(expr(PRE_SIMPLIFICATION)) is DERIVATIVE.