Some checks failed
CI / Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} (x64, ubuntu-latest, 1.10) (push) Has been cancelled
CI / Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} (x64, ubuntu-latest, 1.6) (push) Has been cancelled
CI / Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} (x64, ubuntu-latest, pre) (push) Has been cancelled
147 lines
4.4 KiB
Julia
147 lines
4.4 KiB
Julia
module ExpressionProcessing
|
|
|
|
export expr_to_postfix
|
|
export PostfixType
|
|
export Operator, ADD, SUBTRACT, MULTIPLY, DIVIDE, POWER, ABS, LOG, EXP, SQRT
|
|
export ElementType, EMPTY, FLOAT64, OPERATOR, INT64
|
|
export ExpressionElement
|
|
|
|
@enum Operator::Int64 ADD=1 SUBTRACT=2 MULTIPLY=3 DIVIDE=4 POWER=5 ABS=6 LOG=7 EXP=8 SQRT=9
|
|
@enum ElementType EMPTY=0 FLOAT64=1 OPERATOR=2 INT64=3
|
|
|
|
struct ExpressionElement
|
|
Type::ElementType
|
|
Value::Int64 # Reinterpret the stored value to type "ElementType" when using it
|
|
end
|
|
|
|
const PostfixType = Vector{ExpressionElement}
|
|
|
|
"Converts a julia expression to its postfix notation"
|
|
function expr_to_postfix(expr::Expr)::PostfixType
|
|
postfix = PostfixType()
|
|
operator = get_operator(expr.args[1])
|
|
|
|
# push!(postfix, expr.args[2], expr.args[3], operator)
|
|
for j in 2:length(expr.args)
|
|
arg = expr.args[j]
|
|
if typeof(arg) === Expr
|
|
# exprElement = convert_to_ExpressionElement()
|
|
append!(postfix, expr_to_postfix(arg))
|
|
elseif typeof(arg) === Symbol # variables/parameters
|
|
exprElement = convert_to_ExpressionElement(convert_var_to_int(arg))
|
|
push!(postfix, exprElement)
|
|
else
|
|
exprElement = convert_to_ExpressionElement(convert(Float64, arg))
|
|
push!(postfix, exprElement)
|
|
end
|
|
if length(postfix) >= 2
|
|
exprElement = convert_to_ExpressionElement(operator)
|
|
push!(postfix, exprElement)
|
|
end
|
|
end
|
|
|
|
return postfix
|
|
end
|
|
|
|
function get_operator(op::Symbol)::Operator
|
|
if op == :+
|
|
return ADD
|
|
elseif op == :-
|
|
return SUBTRACT
|
|
elseif op == :*
|
|
return MULTIPLY
|
|
elseif op == :/
|
|
return DIVIDE
|
|
elseif op == :^
|
|
return POWER
|
|
elseif op == :abs
|
|
return ABS
|
|
elseif op == :log
|
|
return LOG
|
|
elseif op == :exp
|
|
return EXP
|
|
elseif op == :sqrt
|
|
return SQRT
|
|
end
|
|
end
|
|
|
|
"Extracts the number from a variable/parameter and returns it. If the symbol is a parameter ```pn```, the resulting value will be negativ.
|
|
|
|
```x0 and p0``` are not allowed."
|
|
function convert_var_to_int(var::Symbol)::Int
|
|
varStr = String(var)
|
|
number = parse(Int32, SubString(varStr, 2))
|
|
|
|
if varStr[1] == 'p'
|
|
number = -number
|
|
end
|
|
|
|
return number
|
|
end
|
|
|
|
function convert_to_ExpressionElement(element)::ExpressionElement
|
|
Value = reinterpret(Int64, element)
|
|
if element isa Float64
|
|
return ExpressionElement(FLOAT64, Value)
|
|
elseif element isa Int64
|
|
return ExpressionElement(INT64, Value)
|
|
elseif element isa Operator
|
|
return ExpressionElement(OPERATOR, Value)
|
|
else
|
|
error("Element was of type '$(typeof(element))', which is not supported.")
|
|
end
|
|
end
|
|
|
|
|
|
|
|
#
|
|
# Everything below is currently not needed. Left here for potential future use
|
|
#
|
|
|
|
const SymbolTable64 = Dict{Tuple{Expr, Symbol},Float64}
|
|
|
|
"Replaces all the variables and parameters of the given expression with their corresponding Value stored in the symtable
|
|
# Arguments
|
|
- `symtable::SymbolTable64`: Contains the values of all variables for each expression
|
|
- `originalExpr::Expr`: Contains a deep copy of the original expression. It is used to link the expression and variables to their according Value stored in the symtable
|
|
"
|
|
function replace_variables!(ex::Expr, symtable::SymbolTable64, originalExpr::Expr)
|
|
for i in 1:length(ex.args)
|
|
arg = ex.args[i]
|
|
if typeof(arg) === Expr
|
|
replace_variables!(arg, symtable, originalExpr)
|
|
elseif haskey(symtable, (originalExpr,arg)) # We found a variable/parameter and can replace it with the actual Value
|
|
ex.args[i] = symtable[(originalExpr,arg)]
|
|
end
|
|
end
|
|
end
|
|
|
|
# TODO: Completly rewrite this function because I misunderstood it. Not every column is linked to an expression. therefore all other functions need to be reworked as well. Probably can't replace the variables in julia anymore, look into this. (see ExpressionExecutorCuda.jl for more info)
|
|
# Before rewriting, proceed with just creating a postfix notation and sending the variable matrix as well as the parameter "matrix" to the GPU to perform first calculations
|
|
function construct_symtable(expressions::Vector{Expr}, mat::Matrix{Float64}, params::Vector{Vector{Float64}})::SymbolTable64
|
|
symtable = SymbolTable64()
|
|
|
|
for i in eachindex(expressions)
|
|
expr = expressions[i]
|
|
values = mat[i,:]
|
|
parameters = params[i]
|
|
|
|
fill_symtable!(expr, symtable, values, "x")
|
|
fill_symtable!(expr, symtable, parameters, "p")
|
|
end
|
|
|
|
return symtable
|
|
end
|
|
|
|
function fill_symtable!(expr::Expr, symtable::SymbolTable64, values::Vector{Float64}, symbolPrefix::String)
|
|
varIndex = 1
|
|
for j in eachindex(values)
|
|
val = values[j]
|
|
sym = Symbol(symbolPrefix, varIndex)
|
|
|
|
symtable[expr,sym] = val
|
|
varIndex += 1
|
|
end
|
|
end
|
|
|
|
end |