{"id":21204932,"url":"https://github.com/pcarruscag/mel","last_synced_at":"2026-05-19T17:33:20.474Z","repository":{"id":197467969,"uuid":"442208479","full_name":"pcarruscag/MEL","owner":"pcarruscag","description":"Math Expression Library","archived":false,"fork":false,"pushed_at":"2024-01-08T03:07:49.000Z","size":109,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-21T15:25:06.442Z","etag":null,"topics":["cpp","expression-evaluation","expression-parsing"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pcarruscag.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-12-27T16:13:56.000Z","updated_at":"2024-05-05T10:59:38.000Z","dependencies_parsed_at":null,"dependency_job_id":"5762a426-5965-452d-93eb-0542a1d65e98","html_url":"https://github.com/pcarruscag/MEL","commit_stats":null,"previous_names":["pcarruscag/mel"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pcarruscag%2FMEL","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pcarruscag%2FMEL/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pcarruscag%2FMEL/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pcarruscag%2FMEL/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pcarruscag","download_url":"https://codeload.github.com/pcarruscag/MEL/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243658186,"owners_count":20326465,"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":["cpp","expression-evaluation","expression-parsing"],"created_at":"2024-11-20T20:41:56.105Z","updated_at":"2025-12-29T17:51:09.170Z","avatar_url":"https://github.com/pcarruscag.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MEL\n\nMath Expression Library\n\n```c++\nconst auto val = mel::Eval\u003cdouble\u003e(\"sqrt(pow(3,2) + pow(4,2)\");\n```\n\nMEL is a small (~500 loc) header-only C++11 library to parse strings into math expression objects that can be evaluated at runtime, by substituting symbols (e.g. `x`) by runtime values.\nIt can be used, for example, to implement user-defined functions (UDF) in a larger code, in a self-contained way.\n\n![Unit Tests](https://github.com/pcarruscag/mel/actions/workflows/c-cpp.yml/badge.svg)\n![Code QL](https://github.com/pcarruscag/mel/actions/workflows/codeql-analysis.yml/badge.svg)\n\n## Usage\n\nThe two main functions of the library are `Parse` and `Eval`.\n - **Parse** creates an expression object (a tree) for an input string and extracts the symbols into a container, a symbol is a sub-string that cannot be split into more math operations, or interpreted directly as a number. The type (`float`, `double`, etc.) for such constants is a template parameter of the function.\n - **Eval** evaluates an expression tree, the mapping from symbol to value can be specified in two ways, either via a `string -\u003e value` functor (3 argument version), or more efficiently via a `index -\u003e value` functor (2 argument version). In the latter, \"index\" is the position of a symbol in the list of symbols created by `Parse`. The return type for `Eval` is a template parameter, and can be different from the one used in `Parse` (provided the latter can be converted into the former).\n\n**Note**: A single-argument overload of `Eval` is provided for expressions without symbols, it evaluates a string directly (i.e. parses and evaluates). This is a convenience function, it is not efficient when the expression needs to be evaluated multiple times.\nAn additional convenience function, `Print`, can be used to visualize the expression trees produced by `Parse`.\n\n### Example 1\n\nSymbols as strings.\n\n```c++\n#include \u003ccmath\u003e\n#include \u003cmap\u003e\n#include \"mel.hpp\"\n\nconst std::string expr = \"a + \\\"const b\\\" * x + c*pow(x,2)\";\nstd::vector\u003cstd::string\u003e symbols;\nconst auto tree = mel::Parse\u003cdouble\u003e(expr, symbols);\n\n// Assign values to symbols.\nstd::map\u003cstd::string, double\u003e values = {{\"a\", 1}, {\"\\\"const b\\\"\", -1}, {\"c\", 0.5}, {\"x\", 0}};\nauto symbol_to_val = [\u0026values](const std::string\u0026 s) {\n  return values.at(s);\n};\n\n// Evaluate for different values of x.\nfor (double x = 0; x \u003c= 10; x += 0.1) {\n  values.at(\"x\") = x;\n  std::cout \u003c\u003c mel::Eval\u003cdouble\u003e(tree, symbols, symbol_to_val) \u003c\u003c '\\n';\n}\n```\n\n### Example 2\n\nSymbols as indices.\n\n```c++\n#include \u003ccmath\u003e\n#include \u003cvector\u003e\n#include \"mel.hpp\"\n\nconst std::string expr = \"a + \\\"const b\\\" * x + c*pow(x,2)\";\nstd::vector\u003cstd::string\u003e symbols;\nconst auto tree = mel::Parse\u003cdouble\u003e(expr, symbols);\n\n// Assign values to symbol indices, here we know the order is \"a\", \"const b\", \"x\", \"c\",\n// but in a real application this process of (efficiently) mapping symbol indices\n// to indices of recognized symbols (by the app using MEL) can be more involved.\nstd::vector\u003cdouble\u003e values = {1, -1, 0, 0.5};\nauto idx_to_val = [\u0026values](int i) {\n  return values[i];\n};\n\n// Evaluate for different values of x.\nfor (double x = 0; x \u003c= 10; x += 0.1) {\n  values[2] = x;\n  std::cout \u003c\u003c mel::Eval\u003cdouble\u003e(tree, idx_to_val) \u003c\u003c '\\n';\n}\n```\n\n### Default math functions and customization\n\nIn the default configuration, MEL parses the four arithmetic operations (`+-*/`), power and trigonometric functions from [cmath](https://www.cplusplus.com/reference/cmath/), `log`, `exp`, `fabs`, `fmin`, and `fmax`.\nIf the type used for `Eval` only supports simple arithmetic, the macro `MEL_ONLY_ARITHMETIC_OPS` can be defined before including `mel.hpp`.\nThe macros `MEL_SUPPORTED_FUNCTIONS`, `MEL_FUNCTION_CODES`, and `MEL_FUNCTION_IMPLEMENTATIONS`, can be used to fully customize the supported math functions, see `definitions.hpp` for instructions.\n\n**Note**: MEL can only handle functions of 1 or 2 arguments, with a single return value.\n\n## Performance\n\nMEL expressions are between 1 and 100 times slower to evaluate than native C++ (a few benchmarks are included in `tests.hpp`)\nThe best-case scenario is for expressions that use a large number of functions (`pow`, `exp`, etc.) relative to the number of symbols, or when the expression is evaluated in a bandwidth-bound context.\nThe worst-case scenario is for expressions with many repeated symbols (which implies common sub expressions that are not optimized in MEL) used in a compute-bound context.\n\n**Note**: To achieve good performance, the expression trees have a maximum number of nodes (constants, symbols, or operations) defined at compile-time. The default value is 255 (~4KB trees with up to 64bit constants) and can be overriden with macro `MEL_MAX_TREE_SIZE`.\n\n## License\n\n[LGPL-3.0](https://www.gnu.org/licenses/lgpl-3.0.html)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpcarruscag%2Fmel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpcarruscag%2Fmel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpcarruscag%2Fmel/lists"}