{"id":13736621,"url":"https://github.com/HugoGranstrom/symbolicnim","last_synced_at":"2025-05-08T12:33:20.555Z","repository":{"id":41280194,"uuid":"281759981","full_name":"HugoGranstrom/symbolicnim","owner":"HugoGranstrom","description":"A symbolic library written purely in Nim with the ability to compile expressions into efficient functions.","archived":false,"fork":false,"pushed_at":"2020-10-25T11:55:16.000Z","size":177,"stargazers_count":40,"open_issues_count":0,"forks_count":2,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-08-04T03:06:52.788Z","etag":null,"topics":["algebra","derivative","nim","rationals","symbolic-library"],"latest_commit_sha":null,"homepage":"","language":"Nim","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/HugoGranstrom.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-07-22T18:58:50.000Z","updated_at":"2024-07-07T04:22:33.000Z","dependencies_parsed_at":"2022-09-21T00:34:20.445Z","dependency_job_id":null,"html_url":"https://github.com/HugoGranstrom/symbolicnim","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HugoGranstrom%2Fsymbolicnim","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HugoGranstrom%2Fsymbolicnim/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HugoGranstrom%2Fsymbolicnim/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HugoGranstrom%2Fsymbolicnim/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HugoGranstrom","download_url":"https://codeload.github.com/HugoGranstrom/symbolicnim/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224732129,"owners_count":17360416,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algebra","derivative","nim","rationals","symbolic-library"],"created_at":"2024-08-03T03:01:25.190Z","updated_at":"2024-11-15T04:32:10.846Z","avatar_url":"https://github.com/HugoGranstrom.png","language":"Nim","funding_links":[],"categories":["Algorithms"],"sub_categories":["Math"],"readme":"# SymbolicNim\n\n![test](https://github.com/HugoGranstrom/symbolicnim/workflows/test/badge.svg)\n\nA symbolic library written purely in Nim with the ability to compile expressions into efficient functions.\n\n## Requires Nim 1.2.6 to run!\n\n# Basic usage\nSymbolicNim exposes a interface of variables and expressions to the user. Symbolic variables are created with the `newVariable` proc:\n```nim\nlet x = newSymbol(\"x\")\nlet y = newSymbol(\"y\")\n```\nThe name of the variable is used to identify it and is used in printing. If two variables are given the same name, they will be interpreted as equal. If you want to create a lot of variables easily you can do it with the `createSymbols` macro:\n```nim\ncreateSymbols(x, y, coolVar)\n```\nThis is transformed to:\n```nim\nlet x = newSymbol(\"x\")\nlet y = newSymbol(\"y\")\nlet coolVar = newSymbol(\"coolVar\")\n```\nExpressions are created when we do arithmetic with variables and constants:\n```nim\nlet expr1 = 2 * x\nlet expr2 = x * y + 1 - x ^ 2\nlet expr3 = sin(x*y) / cos(2*sym_pi) # sym_pi is an exported variable that SymbolicNim interprets as pi.\nlet expr4 = exp(3*x) * ln(exp(y^5))\n# expressions can be used as well:\nlet expr5 = expr1 - expr2\nlet expr6 = expr4 / expr3\n```\n\n## Derivatives\nSymbolicNim can perform symbolic differentitation:\n```nim\nlet x = newSymbol(\"x\")\nlet y = newSymbol(\"y\")\necho diff(x^2, x) # 2*x\necho diff(sin(2*y), y) # 2*cos(2*y)\necho diff(x^2, x, 2) # d^2/dx^2(x^2) = 2\necho diff(x*y, x, y) # d/dy(d/dx(x*y)) = 1\n```\nAs you can see there are two different ways to call `diff`:\n- ONE variable and an int: `diff(x^2, x, 2)`. That is the second derivative with respect to `x`.\n- A varargs of variables: `diff(x*y, x, y)`. The derivatives are performed from left to right so the first variable is associated with the innermost derivative. \n\nNote: SymbolicNim's simplification algorithms aren't anything to brag about really so expect that some expressions can look quite ugly and long even though there is a \"easy\" simplification that could make it neater.\n\n## Subs\n`subs` does what you would expect, it substitutes one expression with another:\n```nim\necho subs(sin(x+y), x + y, z) # sin(z)\n```\n\n## Taylor expansions\nSymbolicNim can calculate Taylor expansions up to 20 terms at the moment. If we want to get the first 10 terms of the taylor series of `sin(x)` around `x = 0` we just have to:\n```nim\necho taylor(sin(x), x, 0, 10)\n```\n\n# Generating efficient Nim procs\nOne of SymbolicNim's main features is that it can do the symbolic calculations at compiletime and generate a fast Nim proc that get's optimized by the compiler. It could be useful if it's used in a tight loop for example. The syntax for generating the procs is to use the `generate` macro:\n```nim\nlet x {.compileTime.} = newSymbol(\"x\") # we must define all the variables we want to use at compileTime with the {.compileTime.} pragma.\nlet y {.compileTime.} = newSymbol(\"y\")\nlet z {.compileTime.} = newSymbol(\"z\")\nlet exprToCompile {.compileTime.} = exp(x*y) ^ sin(z/x) + 1 # this is the expression we want to generate into a function\nexprToCompile.generate:\n  proc f(x, y, z: float): float\n  proc fInline(x, y, z: float): float {.inline.} # you can define how many procs as you want with pragmas and different types\n\necho f(2.0, 3.0, 4.0)\n```\nThat wasn't that hard, wasn't it? If you are not sure of the types of the arguments you can try `auto` and see if it works. One thing to be aware of is that you must be careful when mixing floats and ints. \n\n# Symbolic Matricies\n\n\n## Constants\nSymbolic constants are represented as Nim's stdlib `Rational[int]` from [rationals](https://nim-lang.org/docs/rationals.html). Ints and floats are automatically converted to it when entered. Hence if you input a float it will be converted to the best matching fraction and the output may look quite ugly. If you want to write a fraction exactly you can use the `//` proc that will create a Rational:\n```nim\nlet frac = 1 // 3 # exactly 1 / 3 and not 0.3333333333332 or something.\n```\n\n# Status: Alpha\nThis package is in it's very first stages and will have tonnes of bugs everywhere. If you find something not working, I would very much appreciate if you filed a issue :D\n\n# Credits\n- @jiro4989 for adding the CI workflow.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FHugoGranstrom%2Fsymbolicnim","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FHugoGranstrom%2Fsymbolicnim","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FHugoGranstrom%2Fsymbolicnim/lists"}