Esempio n. 1
0
def test_getVariables():

    varA = getTokens("x")
    assert getVariables([varA]) == ['x']

    varB = getTokens("xy+ xy^2 +yz^3")
    assert getVariables(varB) == ['x', 'y', 'z']
Esempio n. 2
0
def test_getVariables():

    varA = getTokens("x")
    assert getVariables([varA]) == ['x']

    varB = getTokens("xy+ xy^2 +yz^3")
    assert getVariables(varB) == ['x', 'y', 'z']

    varC = getTokens("x + sin(x) + cos(y) + tan(2*z)*2 + tanh(z) + e^2")
    # FIXME: getVariables() in visma.io.checks
    # varC = getTokens("x + sin(x) + cos(y) + tan(2*z)*2 + tanh(z) + e^2")
    # assert getVariables(varC) == ['x', 'y', 'z']
    assert getVariables(varC) == ['x']
Esempio n. 3
0
def plot(workspace, tokens=None):
    """When called from window.py it initiates rendering of equations.

    Arguments:
        workspace {QtWidgets.QWidget} -- main layout
    """
    from visma.io.tokenize import tokenizer

    workspace.figure2D.clear()
    workspace.figure3D.clear()
    if tokens is None:
        tokens = workspace.eqToks[-1]
    eqType = getTokensType(tokens)
    LHStok, RHStok = getLHSandRHS(tokens)
    variables = sorted(getVariables(LHStok, RHStok))
    dim = len(variables)
    graphVars, func, variables = graphPlot(workspace, False, tokens)
    renderPlot(workspace, graphVars, func, variables, tokens)
    if (dim == 1):
        var2, var3 = selectAdditionalVariable(variables[0])
        if tokens is None:
            workspace.eqToks[-1] += tokenizer("0" + var2 + "+" + "0" + var3)
        else:
            tokens += tokenizer("0" + var2 + "+" + "0" + var3)
    if (((dim == 2) or (dim == 1)) & (eqType == 'equation')):
        graphVars, func, variables = graphPlot(workspace, True, tokens)
        renderPlot(workspace, graphVars, func, variables, tokens)
Esempio n. 4
0
def graphPlot(workspace):
    """Function for plotting graphs in 2D and 3D space

    2D graphs are plotted for expression in one variable and equations in two variables. 3D graphs are plotted for expressions in two variables and equations in three variables.

    Arguments:
        workspace {QtWidgets.QWidget} -- main layout

    Returns:
        graphVars {list} -- variables to be plotted on the graph
        func {numpy.array(2D)/function(3D)} -- equation converted to compatible data type for plotting
        variables {list} -- variables in given equation

    Note:
        The func obtained from graphPlot() funtion is of different type for 2D and 3D plots. For 2D, func is a numpy array, and for 3D, func is a function.
    """
    tokens = workspace.eqToks[-1]
    axisRange = workspace.axisRange
    eqType = getTokensType(tokens)
    LHStok, RHStok = getLHSandRHS(tokens)
    variables = sorted(getVariables(LHStok, RHStok))
    dim = len(variables)
    if (dim == 1 and eqType == "expression") or ((dim == 2)
                                                 and eqType == "equation"):
        graphVars, func = plotIn2D(LHStok, RHStok, variables, axisRange)
        if dim == 1:
            variables.append('f(' + variables[0] + ')')
    elif (dim == 2 and eqType == "expression") or ((dim == 3)
                                                   and eqType == "equation"):
        graphVars, func = plotIn3D(LHStok, RHStok, variables, axisRange)
        if dim == 2:
            variables.append('f(' + variables[0] + ',' + variables[1] + ')')
    else:
        return [], None, None
    return graphVars, func, variables
Esempio n. 5
0
def getPowerRatio(initTok, givenTok):
    """Returns ratio of power of given token to power of token to be substituted

    Arguments:
        initTok {functions.structure.Function} -- token to be substituted
        givenTok {functions.structure.Function} -- given token

    Returns:
        ratio {float} -- ratio of givenTok.power to initTok.power
    """

    if isinstance(initTok, Variable) and isinstance(givenTok, Variable):
        varA = getVariables([initTok])
        varB = getVariables([givenTok])
        if all(var in varB for var in varA):
            ratios = []
            for i, valA in enumerate(initTok.value):
                for j, valB in enumerate(givenTok.value):
                    if valA == valB:
                        ratios.append(givenTok.power[j]/initTok.power[i])
                        break
            if all(ratio == ratios[0] for ratio in ratios):
                return ratios[0]
    return 1
Esempio n. 6
0
def plot(workspace):
    """When called from window.py it initiates rendering of equations.

    Arguments:
        workspace {QtWidgets.QWidget} -- main layout
    """
    workspace.figure2D.clear()
    workspace.figure3D.clear()

    tokens = workspace.eqToks[-1]
    eqType = getTokensType(tokens)
    LHStok, RHStok = getLHSandRHS(tokens)
    variables = sorted(getVariables(LHStok, RHStok))
    dim = len(variables)

    graphVars, func, variables = graphPlot(workspace, False)
    renderPlot(workspace, graphVars, func, variables)

    # Handles case when a equation (like x^2 + y^2 = 5) can be rendered in 2D as well as 3D.
    if ((dim == 2) and eqType == "equation"):
        graphVars, func, variables = graphPlot(workspace, True)
        renderPlot(workspace, graphVars, func, variables)
Esempio n. 7
0
 def calluser():
     availableOperations = []
     tokenString = ''
     equationTokens = []
     self.resultOut = True
     if name == 'addition':
         if self.solutionType == 'expression':
             self.tokens, availableOperations, tokenString, equationTokens, comments = addition(
                 self.tokens, True)
         else:
             self.lTokens, self.rTokens, availableOperations, tokenString, equationTokens, comments = additionEquation(
                 self.lTokens, self.rTokens, True)
     elif name == 'subtraction':
         if self.solutionType == 'expression':
             self.tokens, availableOperations, tokenString, equationTokens, comments = subtraction(
                 self.tokens, True)
         else:
             self.lTokens, self.rTokens, availableOperations, tokenString, equationTokens, comments = subtractionEquation(
                 self.lTokens, self.rTokens, True)
     elif name == 'multiplication':
         if self.solutionType == 'expression':
             self.tokens, availableOperations, tokenString, equationTokens, comments = multiplication(
                 self.tokens, True)
         else:
             self.lTokens, self.rTokens, availableOperations, tokenString, equationTokens, comments = multiplicationEquation(
                 self.lTokens, self.rTokens, True)
     elif name == 'division':
         if self.solutionType == 'expression':
             self.tokens, availableOperations, tokenString, equationTokens, comments = division(
                 self.tokens, True)
         else:
             self.lTokens, self.rTokens, availableOperations, tokenString, equationTokens, comments = divisionEquation(
                 self.lTokens, self.rTokens, True)
     elif name == 'simplify':
         if self.solutionType == 'expression':
             self.tokens, availableOperations, tokenString, equationTokens, comments = simplify(
                 self.tokens)
         else:
             self.lTokens, self.rTokens, availableOperations, tokenString, equationTokens, comments = simplifyEquation(
                 self.lTokens, self.rTokens)
     elif name == 'factorize':
         self.tokens, availableOperations, tokenString, equationTokens, comments = factorize(
             self.tokens)
     elif name == 'find roots':
         self.lTokens, self.rTokens, availableOperations, tokenString, equationTokens, comments = quadraticRoots(
             self.lTokens, self.rTokens)
     elif name == 'solve':
         lhs, rhs = getLHSandRHS(self.tokens)
         variables = getVariables(lhs, rhs)
         self.wrtVariableButtons(variables, name)
         self.resultOut = False
     elif name == 'integrate':
         lhs, rhs = getLHSandRHS(self.tokens)
         variables = getVariables(lhs, rhs)
         self.wrtVariableButtons(variables, name)
         self.resultOut = False
     elif name == 'differentiate':
         lhs, rhs = getLHSandRHS(self.tokens)
         variables = getVariables(lhs, rhs)
         self.wrtVariableButtons(variables, name)
         self.resultOut = False
     if self.resultOut:
         self.eqToks = equationTokens
         self.output = resultLatex(name, equationTokens, comments)
         if len(availableOperations) == 0:
             self.clearButtons()
         else:
             self.refreshButtons(availableOperations)
         if self.mode == 'normal':
             self.textedit.setText(tokenString)
         elif self.mode == 'interaction':
             cursor = self.textedit.textCursor()
             cursor.insertText(tokenString)
         if self.showStepByStep is True:
             showSteps(self)
         if self.showPlotter is True:
             plot(self)
Esempio n. 8
0
def cubicRoots(lTokens, rTokens):
    '''Used to get roots of a cubic equation
    This functions also translates roots {list} into final result of solution

    Argument:
        lTokens {list} -- list of LHS tokens
        rTokens {list} -- list of RHS tokens

    Returns:
        lTokens {list} -- list of LHS tokens
        rTokens {list} -- list of RHS tokens
        {empty list}
        token_string {string} -- final result stored in a string
        animation {list} -- list of equation solving process
        comments {list} -- list of comments in equation solving process
    '''
    from visma.solvers.polynomial.roots import getCoefficients

    animations = []
    comments = []
    lTokens, rTokens, _, token_string, animNew1, commentNew1 = simplifyEquation(
        lTokens, rTokens)
    animations.extend(animNew1)
    comments.extend(commentNew1)
    if len(rTokens) > 0:
        lTokens, rTokens = moveRTokensToLTokens(lTokens, rTokens)
    coeffs = getCoefficients(lTokens, rTokens, 3)
    var = getVariables(lTokens)
    roots, animNew2, commentNew2 = getRootsCubic(coeffs)
    animations.extend(animNew2)
    comments.extend(commentNew2)
    tokens1 = []
    expression1 = Expression(coefficient=1, power=3)
    variable = Variable(1, var[0], 1)
    tokens1.append(variable)
    if roots[0][1] == 0:
        binary = Binary()
        if roots[0][0] < 0:
            roots[0][0] *= -1
            binary.value = '+'
        else:
            binary.value = '-'
        tokens1.append(binary)
    constant = Constant(round(roots[0][0], ROUNDOFF), 1)
    tokens1.append(constant)

    expression1.tokens = tokens1
    lTokens = [expression1, Binary('*')]

    if len(roots) > 1:
        expression1.power = 1
        for _, root in enumerate(roots[1:]):
            tokens2 = []
            expression2 = Expression(coefficient=1, power=1)
            variable = Variable(1, var[0], 1)
            tokens2.append(variable)
            binary = Binary()
            if root[1] == 0:
                if root[0] < 0:
                    root[0] *= -1
                    binary.value = '+'
                else:
                    binary.value = '-'
                tokens2.append(binary)
                constant = Constant(round(root[0], ROUNDOFF), 1)
                tokens2.append(constant)
            else:
                binary.value = '-'
                tokens2.append(binary)
                expressionResult = Expression(coefficient=1, power=1)
                tokensResult = []
                real = Constant(round(root[0], ROUNDOFF), 1)
                tokensResult.append(real)
                imaginary = Constant(round(root[1], ROUNDOFF), 1)
                if imaginary.value < 0:
                    tokensResult.append(Minus())
                    imaginary.value = abs(imaginary.value)
                    tokensResult.append(imaginary)
                else:
                    tokensResult.extend([Plus(), imaginary])
                sqrt = Sqrt(Constant(2, 1), Constant(-1, 1))
                tokensResult.append(Binary('*'))
                tokensResult.append(sqrt)
                expressionResult.tokens = tokensResult
                tokens2.append(expressionResult)
            expression2.tokens = tokens2
            lTokens.extend([expression2, Binary('*')])
    lTokens.pop()
    rTokens = [Zero()]
    tokenToStringBuilder = copy.deepcopy(lTokens)
    tokLen = len(lTokens)
    equalTo = Binary()
    equalTo.scope = [tokLen]
    equalTo.value = '='
    tokenToStringBuilder.append(equalTo)
    tokenToStringBuilder.extend(rTokens)
    token_string = tokensToString(tokenToStringBuilder)
    animations.append(copy.deepcopy(tokenToStringBuilder))
    comments.append([])
    return lTokens, rTokens, [], token_string, animations, comments
Esempio n. 9
0
        def calluser():
            availableOperations = []
            tokenString = ''
            equationTokens = []
            self.resultOut = True
            if not self.matrix:
                """
                This part handles the cases when VisMa is NOT dealing with matrices.

                Boolean flags used in code below:
                simul -- {True} when VisMa is dealing with simultaneous equations & {False} in all other cases
                """
                if name == 'addition':
                    if self.solutionType == 'expression':
                        self.tokens, availableOperations, tokenString, equationTokens, comments = addition(
                            self.tokens, True)
                    else:
                        self.lTokens, self.rTokens, availableOperations, tokenString, equationTokens, comments = additionEquation(
                            self.lTokens, self.rTokens, True)
                elif name == 'subtraction':
                    if self.solutionType == 'expression':
                        self.tokens, availableOperations, tokenString, equationTokens, comments = subtraction(
                            self.tokens, True)
                    else:
                        self.lTokens, self.rTokens, availableOperations, tokenString, equationTokens, comments = subtractionEquation(
                            self.lTokens, self.rTokens, True)
                elif name == 'multiplication':
                    if self.solutionType == 'expression':
                        self.tokens, availableOperations, tokenString, equationTokens, comments = multiplication(
                            self.tokens, True)
                    else:
                        self.lTokens, self.rTokens, availableOperations, tokenString, equationTokens, comments = multiplicationEquation(
                            self.lTokens, self.rTokens, True)
                elif name == 'division':
                    if self.solutionType == 'expression':
                        self.tokens, availableOperations, tokenString, equationTokens, comments = division(
                            self.tokens, True)
                    else:
                        self.lTokens, self.rTokens, availableOperations, tokenString, equationTokens, comments = divisionEquation(
                            self.lTokens, self.rTokens, True)
                elif name == 'simplify':
                    if self.solutionType == 'expression':
                        self.tokens, availableOperations, tokenString, equationTokens, comments = simplify(self.tokens)
                    else:
                        self.lTokens, self.rTokens, availableOperations, tokenString, equationTokens, comments = simplifyEquation(self.lTokens, self.rTokens)
                elif name == 'factorize':
                    self.tokens, availableOperations, tokenString, equationTokens, comments = factorize(self.tokens)
                elif name == 'find roots':
                    self.lTokens, self.rTokens, availableOperations, tokenString, equationTokens, comments = rootFinder(self.lTokens, self.rTokens)
                elif name == 'solve':
                    if not self.simul:
                        lhs, rhs = getLHSandRHS(self.tokens)
                        variables = getVariables(lhs, rhs)
                    else:
                        variables = getVariableSim(self.tokens)
                    self.wrtVariableButtons(variables, name)
                    self.resultOut = False
                elif name == 'factorial':
                    self.tokens, availableOperations, tokenString, equationTokens, comments = factorial(self.tokens)
                elif name == 'combination':
                    nTokens = self.tokens[0]
                    rTokens = self.tokens[1]
                    self.tokens, _, _, equationTokens, comments = combination(nTokens, rTokens)
                elif name == 'permutation':
                    nTokens = self.tokens[0]
                    rTokens = self.tokens[1]
                    self.tokens, _, _, equationTokens, comments = permutation(nTokens, rTokens)
                elif name == 'integrate':
                    lhs, rhs = getLHSandRHS(self.tokens)
                    variables = getVariables(lhs, rhs)
                    self.wrtVariableButtons(variables, name)
                    self.resultOut = False
                elif name == 'differentiate':
                    lhs, rhs = getLHSandRHS(self.tokens)
                    variables = getVariables(lhs, rhs)
                    self.wrtVariableButtons(variables, name)
                    self.resultOut = False
            else:
                """
                This part handles the cases when VisMa is dealing with matrices.

                Boolean flags used in code below:
                dualOperand -- {True} when the matrix operations require two operands (used in operations like addition, subtraction etc)
                nonMatrixResult -- {True} when the result after performing operations on the Matrix is not a Matrix (in operations like Determinant, Trace etc.)
                scalarOperations -- {True} when one of the operand in a scalar (used in operations like Scalar Addition, Scalar Subtraction etc.)
                """
                #   TODO: use latex tools like /amsmath for displaying matrices
                if self.dualOperandMatrix:
                    Matrix1_copy = copy.deepcopy(self.Matrix1)
                    Matrix2_copy = copy.deepcopy(self.Matrix2)
                else:
                    Matrix0_copy = copy.deepcopy(self.Matrix0)
                if name == 'Addition':
                    MatrixResult = addMatrix(self.Matrix1, self.Matrix2)
                elif name == 'Subtraction':
                    MatrixResult = subMatrix(self.Matrix1, self.Matrix2)
                elif name == 'Multiply':
                    MatrixResult = multiplyMatrix(self.Matrix1, self.Matrix2)
                elif name == 'Simplify':
                    MatrixResult = simplifyMatrix(self.Matrix0)
                elif name == 'Trace':
                    sqMatrix = SquareMat()
                    sqMatrix.value = self.Matrix0.value
                    result = sqMatrix.traceMat()
                elif name == 'Determinant':
                    sqMatrix = SquareMat()
                    sqMatrix.value = self.Matrix0.value
                    result = sqMatrix.determinant()
                elif name == 'Inverse':
                    sqMatrix = SquareMat()
                    sqMatrix.value = self.Matrix0.value
                    MatrixResult = SquareMat()
                    MatrixResult = sqMatrix.inverse()
                if name in ['Addition', 'Subtraction', 'Multiply']:
                    self.dualOperandMatrix = True
                else:
                    self.dualOperandMatrix = False
                if name in ['Determinant', 'Trace']:
                    self.nonMatrixResult = True
                else:
                    self.nonMatrixResult = False
            if self.resultOut:
                if not self.matrix:
                    self.eqToks = equationTokens
                    self.output = resultLatex(equationTokens, name, comments, self.solutionType)
                    if (mathError(self.eqToks[-1])):
                        self.output += 'Math Error: LHS not equal to RHS' + '\n'
                    if len(availableOperations) == 0:
                        self.clearButtons()
                    else:
                        self.refreshButtons(availableOperations)
                    if self.mode == 'normal':
                        self.textedit.setText(tokenString)
                    elif self.mode == 'interaction':
                        cursor = self.textedit.textCursor()
                        cursor.insertText(tokenString)
                    if self.showStepByStep is True:
                        showSteps(self)
                    if self.showPlotter is True:
                        plot(self)
                else:
                    if self.dualOperandMatrix:
                        if not self.scalarOperationsMatrix:
                            self.output = resultMatrixStringLatex(operation=name, operand1=Matrix1_copy, operand2=Matrix2_copy, result=MatrixResult)
                        else:
                            # TODO: Implement Scalar Matrices operations.
                            pass
                            # finalCLIstring = resultMatrix_Latex(operation=name, operand1=scalarTokens_copy, operand2=Matrix2_copy, result=MatrixResult)
                    else:
                        if self.nonMatrixResult:
                            self.output = resultMatrixStringLatex(operation=name, operand1=Matrix0_copy, nonMatrixResult=True, result=result)
                        else:
                            self.output = resultMatrixStringLatex(operation=name, operand1=Matrix0_copy, result=MatrixResult)
                    if self.mode == 'normal':
                        self.textedit.setText(tokenString)
                    elif self.mode == 'interaction':
                        cursor = self.textedit.textCursor()
                        cursor.insertText(tokenString)
                    if self.showStepByStep is True:
                        showSteps(self)
Esempio n. 10
0
def quadraticRoots(lTokens, rTokens):
    '''Used to get quadratic roots of an equation

    Argument:
        lTokens {list} -- list of LHS tokens
        rTokens {list} -- list of RHS tokens

    Returns:
        lTokens {list} -- list of LHS tokens
        rTokens {list} -- list of RHS tokens
        {empty list}
        token_string {string} -- final result stored in a string
        animation {list} -- list of equation solving process
        comments {list} -- list of comments in equation solving process
    '''
    from visma.solvers.polynomial.roots import getCoefficients

    animations = []
    comments = []
    lTokens, rTokens, _, token_string, animNew1, commentNew1 = simplifyEquation(lTokens, rTokens)
    animations.extend(animNew1)
    comments.extend(commentNew1)
    if len(rTokens) > 0:
        lTokens, rTokens = moveRTokensToLTokens(lTokens, rTokens)
    coeffs = getCoefficients(lTokens, rTokens, 2)
    var = getVariables(lTokens)
    roots, animNew2, commentNew2 = getRootsQuadratic(coeffs)
    animations.extend(animNew2)
    comments.extend(commentNew2)
    if len(roots) == 1:
        tokens = []
        expression = Expression(coefficient=1, power=2)
        variable = Variable(1, var[0], 1)
        tokens.append(variable)
        binary = Binary()
        if roots[0] < 0:
            roots[0] *= -1
            binary.value = '+'
        else:
            binary.value = '-'
        tokens.append(binary)
        constant = Constant(round(roots[0], ROUNDOFF), 1)
        tokens.append(constant)
        expression.tokens = tokens
        lTokens = [expression]

    elif len(roots) == 2:
        tokens = []
        expression = Expression(coefficient=1, power=1)
        variable = Variable(1, var[0], 1)
        tokens.append(variable)
        binary = Binary()
        if roots[0] < 0:
            roots[0] *= -1
            binary.value = '+'
        else:
            binary.value = '-'
        tokens.append(binary)
        constant = Constant(round(roots[0], ROUNDOFF), 1)
        tokens.append(constant)
        expression.tokens = tokens

        tokens2 = []
        expression2 = Expression(coefficient=1, power=1)
        tokens2.append(variable)
        binary2 = Binary()
        if roots[1] < 0:
            roots[1] *= -1
            binary2.value = '+'
        else:
            binary2.value = '-'
        tokens2.append(binary2)
        constant2 = Constant(round(roots[1], ROUNDOFF), 1)
        tokens2.append(constant2)
        expression2.tokens = tokens2

        binary3 = Binary()
        binary3.value = '*'
        lTokens = [expression, binary3, expression2]

    elif len(roots) == 3:
        binary4 = Binary()
        if roots[0] < 0:
            roots[0] *= -1
            binary4.value = '+'
        else:
            binary4.value = '-'

        constant3 = Constant(round(roots[0], ROUNDOFF), 1)

        binary5 = Binary()
        binary5.value = '*'

        constant2 = Constant(round(roots[2], ROUNDOFF), 1)

        tokens = []
        expression = Expression(coefficient=1, power=1)
        variable = Variable(1, var[0], 1)
        tokens.extend([variable, binary4, constant3])
        binary = Binary()
        binary.value = '+'
        tokens.extend([binary, constant2, binary5])
        constant = Constant(round(roots[1], ROUNDOFF), 1)
        sqrt = Sqrt(Constant(2, 1), constant)
        tokens.append(sqrt)
        expression.tokens = tokens

        tokens2 = []
        expression2 = Expression(coefficient=1, power=1)
        variable2 = Variable(1, var[0], 1)
        tokens2.extend([variable2, binary4, constant3])
        binary2 = Binary()
        binary2.value = '-'
        tokens2.extend([binary2, constant2, binary5, sqrt])
        expression2.tokens = tokens2
        binary3 = Binary()
        binary3.value = '*'
        lTokens = [expression, binary3, expression2]

    zero = Zero()
    rTokens = [zero]
    comments.append([])
    tokenToStringBuilder = copy.deepcopy(lTokens)
    tokLen = len(lTokens)
    equalTo = Binary()
    equalTo.scope = [tokLen]
    equalTo.value = '='
    tokenToStringBuilder.append(equalTo)
    tokenToStringBuilder.extend(rTokens)
    animations.append(copy.deepcopy(tokenToStringBuilder))
    token_string = tokensToString(tokenToStringBuilder)
    return lTokens, rTokens, [], token_string, animations, comments