# 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

(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

``````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