Symbolic Substitution


#1

Hi All,

Is there a way to carryout symbolic substitution over an expression. Something similar to:
a=2; b=1
substitute(a,b,1/(a+b)) to result to 1/(2+1) and not 1/3

Thanks in advance.


(Christoph Rüegg) #2

There is Structure.substitute that can do such substitutions, but there is no way to prevent 1/(2+1) from being auto-symplified to 1/3 (unless maybe declaring them somehow as constants).


#3

Thanks for the quick response!

Is there a way to obtain the symble’s string name after assigning a value to the variable? If there is, then I can replace that symble’s string name with a value. Below is my attempt to explain the above idea (by the way, I am not a programmer, so please bear with my bad coding skills)

    Dim a = MathNet.Symbolics.Expression.Symbol("a")
    Dim b = MathNet.Symbolics.Expression.Symbol("b")

    Dim c = 1 / (a + b)
    a = 2
    b = 3


    Dim str1 As String
    Dim str2 As String
    Dim str3 As String

    str1 = Infix.Print(c)



    str2 = str1.Replace("a", Infix.Print(a))      **'how can I get "a" from the variable a**
    str2 = str2.Replace("b", Infix.Print(b))       **'how can I get "b" from the variable b**


    str3 = str1 + "=" + str2 + "=" + Infix.Print(Infix.ParseOrThrow(str2))


    MsgBox(str3)  ' 1/(a + b)=1/(2 + 3)=1/5 **_This is the final results I want_**

(Christoph Rüegg) #4

Instead of

str2 = str1.Replace("a", Infix.Format(a))

you can write

str2 = str1.Replace(NameOf(a), Infix.Format(a))

Is that what you’re looking for?


(Christoph Rüegg) #5

Note that there may be some confusion here about two different contexts that both offer some concept of a “variable” with a name - first that of your programming language (i.e. the a in Dim a = ..) and second the Math.NET Symbolics symbol (i.e. the a in Expression.Symbol("a")). Maybe this is clearer if we write:

Dim aa = MathNet.Symbolics.Expression.Symbol("a")

Such that aa refers to the variable and a to the symbol. Infix.Format(aa) will then return "a".

Whe you then write:

aa = 2

then you do not actually change the symbol a at all, instead you redefine your variable aa to now have the new value 2 instead of a.

While you can change the value of programming language variables (aa) freely, you cannot actually “assign” a value to the Symbolics symbol a. That’s why it is called “symbol”, nor “variable”.


#6

Things are starting to get clearer. str2 = str1.Replace(NameOf(a), Infix.Format(a)) is definitely a good workaround. Please confirm the two following points:

  1. If I understand you clearly, there is no way I can retrieve Math.NET Symbolics symbol (i.e. the a in Expression.Symbol(“a”)) after assigning a value to it. Below is a code showing what I mean
    Dim aa = MathNet.Symbolics.Expression.Symbol(“a”)
    aa = 2 ’ aa has lost the symbol “a” and it would always show 2 (unless another value assigned)

  2. The same apply with expressions/equations. Below is what I mean
    Dim aa = MathNet.Symbolics.Expression.Symbol(“a”)
    Dim b = MathNet.Symbolics.Expression.Symbol(“b”)

     aa = 2 
     b = 3 
    
     Dim c = 1 / (aa + b) 
    
     MsgBox(Infix.Print(c)) 'output "1/5"  as long as aa and b are assigned values before creating c. There is no way to show "c = 1 / (a+ b)" instead of "1/5"

#7

Why don’t you define the expression as string and then just show the result?
Example:


let input = "1/(a+b)"

let test = Infix.parseOrUndefined input

let values = 
    [("a",2.0);("b",3.0)]
    |> Map.ofList
    |> Map.map(fun k v -> FloatingPoint.Real v)

(values,test)
||> Evaluate.evaluate
|> printfn "%s when %A = %A" input values

Print:

1/(a+b) when map [("a", Real 2.0); ("b", Real 3.0)] = Real 0.2

You can customize the output as you wish, this is just an example.


#8

I am not very familiar with F#. But I think the following two functions more or less are a vb.net translation of your code.

Function Print_Detailed_Calculation(ByVal Symble_And_Values As Dictionary(Of String, FloatingPoint),
ByRef EquationExpression As MathNet.Symbolics.Expression,
ByRef Optional EquationExpression_Name As String = “”) As String

    Dim str As String
    Dim str2 As String

    str = Infix.Format(EquationExpression)
    str2 = str
    For Each item In Symble_And_Values
        str2 = str2.Replace(item.Key, item.Value.RealValue.ToString)
    Next

    If EquationExpression_Name = "" Then
        Print_Detailed_Calculation = str + " = " + str2 + " = " &
                   MathNet.Symbolics.Evaluate.Evaluate(Symble_And_Values,
                                                       EquationExpression).RealValue
    Else
        Print_Detailed_Calculation = EquationExpression_Name + " = " + str + " = " + str2 + " = " &
                    MathNet.Symbolics.Evaluate.Evaluate(Symble_And_Values,
                                                        EquationExpression).RealValue
    End If

End Function


Function Print_Detailed_Calculation(ByVal Symble_And_Values As Dictionary(Of String, FloatingPoint),
                                   ByRef EquationExpression As String,
                                   ByRef Optional EquationExpression_Name As String = "") As String

    Dim exp As MathNet.Symbolics.Expression
    Dim str2 As String

    exp = Infix.ParseOrThrow(EquationExpression)
    str2 = EquationExpression
    For Each item In Symble_And_Values
        str2 = str2.Replace(item.Key, item.Value.RealValue.ToString)
    Next

    If EquationExpression_Name = "" Then
        Print_Detailed_Calculation = EquationExpression + " = " + str2 + " = " &
                   MathNet.Symbolics.Evaluate.Evaluate(Symble_And_Values,
                                                       exp).RealValue
    Else
        Print_Detailed_Calculation = EquationExpression_Name + " = " + EquationExpression + " = " + str2 + " = " &
                    MathNet.Symbolics.Evaluate.Evaluate(Symble_And_Values,
                                                        exp).RealValue
    End If

End Function

(Christoph Rüegg) #9

The new Approximation module seems like it could help in your use case, see Merge terms that contain Expression.Real factors