mirror of
				https://github.com/DanilaFe/abacus
				synced 2025-11-04 02:43:41 -08:00 
			
		
		
		
	Add comments and make minor modifications to the Graph class.
This commit is contained in:
		
							parent
							
								
									bbe4fa182f
								
							
						
					
					
						commit
						2f4362e23b
					
				@ -12,30 +12,66 @@ import org.nwapw.abacus.number.NumberInterface
 | 
				
			|||||||
import org.nwapw.abacus.plugin.StandardPlugin
 | 
					import org.nwapw.abacus.plugin.StandardPlugin
 | 
				
			||||||
import org.nwapw.abacus.tree.TreeNode
 | 
					import org.nwapw.abacus.tree.TreeNode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * A class that holds information about a graph.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Graph that uses an instance of [Abacus] to generate graphs of an
 | 
				
			||||||
 | 
					 * [expression]. Continuous graphing on large expressions is expensive,
 | 
				
			||||||
 | 
					 * and therefore the method of graphing is discrete. The graph class
 | 
				
			||||||
 | 
					 * uses the [pointExpression] to generate inputs until an input is outside
 | 
				
			||||||
 | 
					 * the function's domain. In both the expressions, the [inputVariable] and
 | 
				
			||||||
 | 
					 * [pointInputVariable] are used, respectively, in order to either pass in
 | 
				
			||||||
 | 
					 * the x-coordinate or the number of the input value being generated.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @property abacus the abacus instance to use to evaluate expressions.
 | 
				
			||||||
 | 
					 * @property domain the domain used in computation.
 | 
				
			||||||
 | 
					 * @property range the range used for displaying the output.
 | 
				
			||||||
 | 
					 * @property inputVariable the variable which is substituted for the input x-coordinate.
 | 
				
			||||||
 | 
					 * @property pointInputVariable the variable which is substituted for the number of the input point being generated.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
class Graph(val abacus: Abacus,
 | 
					class Graph(val abacus: Abacus,
 | 
				
			||||||
            expression: String, pointExpression: String,
 | 
					 | 
				
			||||||
            var domain: ClosedRange<NumberInterface>, var range: ClosedRange<NumberInterface>,
 | 
					            var domain: ClosedRange<NumberInterface>, var range: ClosedRange<NumberInterface>,
 | 
				
			||||||
            var inputVariable: String = "x", var pointInputVariable: String = "n") {
 | 
					            var inputVariable: String = "x", var pointInputVariable: String = "n") {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Property used for storing the parsed version of the [expression]
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    private var expressionTree: TreeNode? = null
 | 
					    private var expressionTree: TreeNode? = null
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Property used for storing the parsed version of the [pointExpression]
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    private var pointExpressionTree: TreeNode? = null
 | 
					    private var pointExpressionTree: TreeNode? = null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    var expression: String = ""
 | 
					    /**
 | 
				
			||||||
 | 
					     * The expression being graphed.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    var expression: String? = null
 | 
				
			||||||
        set(value) {
 | 
					        set(value) {
 | 
				
			||||||
            expressionTree = abacus.parseString(value)
 | 
					 | 
				
			||||||
            field = value
 | 
					            field = value
 | 
				
			||||||
 | 
					            expressionTree = abacus.parseString(value ?: return)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    var pointExpression: String = ""
 | 
					    /**
 | 
				
			||||||
 | 
					     * The expression being used to generate points.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    var pointExpression: String? = null
 | 
				
			||||||
        set(value) {
 | 
					        set(value) {
 | 
				
			||||||
            pointExpressionTree = abacus.parseString(value)
 | 
					 | 
				
			||||||
            field = value
 | 
					            field = value
 | 
				
			||||||
 | 
					            pointExpressionTree = abacus.parseString(value ?: return)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    init {
 | 
					    /**
 | 
				
			||||||
        this.expression = expression
 | 
					     * Evaluates a parsed expression [tree] with the given input [values] of indeterminate type.
 | 
				
			||||||
        this.pointExpression = pointExpression
 | 
					     * This is is an asynchronous operation using coroutines, and for every input
 | 
				
			||||||
    }
 | 
					     * value a new sub-context is created. The [contextModifier] function is executed
 | 
				
			||||||
 | 
					     * on each new sub-context, and is expected to use the input value to modify the context
 | 
				
			||||||
 | 
					     * state so that the evaluation of the expression produces a correct result.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param T the type of input values.
 | 
				
			||||||
 | 
					     * @param tree the tree to evaluate.
 | 
				
			||||||
 | 
					     * @param values the values to plug into the expression.
 | 
				
			||||||
 | 
					     * @param contextModifier the function that plugs values into the context.
 | 
				
			||||||
 | 
					     * @return the list of outputs.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    fun <T> evaluateWith(tree: TreeNode, values: List<T>,
 | 
					    fun <T> evaluateWith(tree: TreeNode, values: List<T>,
 | 
				
			||||||
                         contextModifier: MutableEvaluationContext.(T) -> Unit) = runBlocking {
 | 
					                         contextModifier: MutableEvaluationContext.(T) -> Unit) = runBlocking {
 | 
				
			||||||
        values.map {
 | 
					        values.map {
 | 
				
			||||||
@ -45,10 +81,23 @@ class Graph(val abacus: Abacus,
 | 
				
			|||||||
        }.map { it.await() }
 | 
					        }.map { it.await() }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Extension function that calls [evaluateWith] with the current list.
 | 
				
			||||||
 | 
					     * @param T the type of the values in the list.
 | 
				
			||||||
 | 
					     * @param tree the tree node to evaluate.
 | 
				
			||||||
 | 
					     * @param contextModifier the function that plugs values into the context.
 | 
				
			||||||
 | 
					     * @return the list of outputs.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    fun <T> List<T>.evaluateWith(tree: TreeNode,
 | 
					    fun <T> List<T>.evaluateWith(tree: TreeNode,
 | 
				
			||||||
                                 contextModifier: MutableEvaluationContext.(T) -> Unit ) =
 | 
					                                 contextModifier: MutableEvaluationContext.(T) -> Unit ) =
 | 
				
			||||||
            evaluateWith(tree, this, contextModifier)
 | 
					            evaluateWith(tree, this, contextModifier)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Uses the [pointExpression] and [pointInputVariable] to generate
 | 
				
			||||||
 | 
					     * a set of points as inputs for the actual expression. These points are generated
 | 
				
			||||||
 | 
					     * as long as they are within the [domain].
 | 
				
			||||||
 | 
					     * @return the list of generated input values.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    fun generateInputs(): List<NumberInterface> =
 | 
					    fun generateInputs(): List<NumberInterface> =
 | 
				
			||||||
            generateSequence(1) {
 | 
					            generateSequence(1) {
 | 
				
			||||||
                it + 1
 | 
					                it + 1
 | 
				
			||||||
@ -59,8 +108,13 @@ class Graph(val abacus: Abacus,
 | 
				
			|||||||
                abacus.evaluateTreeWithContext(pointExpressionTree!!, context).value
 | 
					                abacus.evaluateTreeWithContext(pointExpressionTree!!, context).value
 | 
				
			||||||
            }.takeWhile { it in domain }.toList()
 | 
					            }.takeWhile { it in domain }.toList()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun generateOutputs(inputs: List<NumberInterface>): List<NumberInterface> =
 | 
					    /**
 | 
				
			||||||
 | 
					     * Uses the [expression] and [inputVariable] to generate
 | 
				
			||||||
 | 
					     * a set of outputs from the given set of [inputs].
 | 
				
			||||||
 | 
					     * @return the list of generated points.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    fun generateOutputs(inputs: List<NumberInterface>): List<Pair<NumberInterface, NumberInterface>> =
 | 
				
			||||||
            inputs.evaluateWith(expressionTree!!) {
 | 
					            inputs.evaluateWith(expressionTree!!) {
 | 
				
			||||||
                setVariable(inputVariable, it)
 | 
					                setVariable(inputVariable, it)
 | 
				
			||||||
            }.map { it.value }
 | 
					            }.mapIndexed { index, (value) -> inputs[index] to value }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user