{"id":25613576,"url":"https://github.com/sajjon/equationkit","last_synced_at":"2025-07-20T15:02:46.903Z","repository":{"id":56910039,"uuid":"144000624","full_name":"Sajjon/EquationKit","owner":"Sajjon","description":"Equations in Swift","archived":false,"fork":false,"pushed_at":"2019-11-08T09:26:33.000Z","size":394,"stargazers_count":45,"open_issues_count":0,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-14T10:06:49.819Z","etag":null,"topics":["equations","mathematics","multivariate-polynomials","partial-derivative","polynomial-arithmetic","swift","swift-framework"],"latest_commit_sha":null,"homepage":null,"language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Sajjon.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":"2018-08-08T10:54:30.000Z","updated_at":"2024-11-04T12:29:25.000Z","dependencies_parsed_at":"2022-08-20T19:50:32.679Z","dependency_job_id":null,"html_url":"https://github.com/Sajjon/EquationKit","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/Sajjon/EquationKit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sajjon%2FEquationKit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sajjon%2FEquationKit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sajjon%2FEquationKit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sajjon%2FEquationKit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Sajjon","download_url":"https://codeload.github.com/Sajjon/EquationKit/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sajjon%2FEquationKit/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266143941,"owners_count":23883069,"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":["equations","mathematics","multivariate-polynomials","partial-derivative","polynomial-arithmetic","swift","swift-framework"],"created_at":"2025-02-22T01:36:11.175Z","updated_at":"2025-07-20T15:02:46.878Z","avatar_url":"https://github.com/Sajjon.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# EquationKit\n\n## Write equations in pure Swift, differentiate and/or evaluate them.\n\n```swift\nlet polynomial = (3*x + 5*y - 17) * (7*x - 9*y + 23)\nprint(polynomial) // 21x² + 8xy - 50x - 45y² + 268y - 391)\nlet number = polynomial.evaluate() {[ x \u003c- 4, y \u003c- 1 ]}\nprint(number) // 0\n\nlet y＇ = polynomial.differentiateWithRespectTo(x)\nprint(y＇) // 42x + 8y - 50\ny＇.evaluate() {[ x \u003c- 1, y \u003c- 1 ]} // 0\n\nlet x＇ = polynomial.differentiateWithRespectTo(y)\nprint(x＇) // 8x - 90y + 268\n x＇.evaluate() {[ x \u003c- 11.5,  y \u003c- 4 ]} // 0\n```\n\n# Installation\n\n## Swift Package Manager\n\n```swift\ndependencies: [\n    .package(url: \"https://github.com/Sajjon/EquationKit\", from: \"0.1.0\")\n]\n```\n\n# Usage\n\n## Generics\nEquationKit is fully generic and supports any number type conforming to the protocol [`NumberExpressible`](Sources/EquationKit/NumberExpressible/NumberExpressible.swift), Swift Foundation's `Int` and `Double` both conforms to said protocol. By conforming to `NumberExpressible` you can use EquationKit with e.g. excellent [attaswift/BigInt](https://github.com/attaswift/BigInt). \n\nYou need only to `import EquationKitBigIntSupport`\n\nWe would like to use operator overloading, making it possible to write `x + y`, `x - 2`, `x*z² - y³` etc. Supporting operator overloading using generic `func + \u003cN: NumberExpressible\u003e(lhs: Variable, rhs: N) -\u003e PolynomialStruct\u003cN\u003e` results in Swift compiler taking too long time to compile polynomials having over 3 terms (using Xcode 10 beta 6 at least). Thus EquationKit does not come bundled with any operator support at all. Instead, you chose your Number type yourself. If you don't need `BigInt` then `Double` is probably what you want, just `import EquationKitDoubleSupport` and you are good to go! It contains around 10 operators which are all 3 lines of code each.\n\n## Variables\nYou write powers using the custom operator `x^^2`, but for powers between `2` and `9` you can use the [unicode superscript symbols](https://en.wikipedia.org/wiki/Unicode_subscripts_and_superscripts#Superscripts_and_subscripts_block) instead, like so:\n```swift\nlet x = Variable(\"x\")\nlet y = Variable(\"y\")\nlet x² = Exponentiation(x, exponent: 2)\nlet x³ = Exponentiation(x, exponent: 3)\nlet x⁴ = Exponentiation(x, exponent: 4)\nlet x⁵ = Exponentiation(x, exponent: 5)\nlet x⁶ = Exponentiation(x, exponent: 6)\nlet x⁷ = Exponentiation(x, exponent: 7)\nlet x⁸ = Exponentiation(x, exponent: 8)\nlet x⁹ = Exponentiation(x, exponent: 9)\n\nlet y² = Exponentiation(y, exponent: 2)\n```\n\n## Advanced operators\nYou can use some of the advanced mathematical operators provided in the folder [MathematicalOperators](Sources/EquationKit/MathematicalOperators) to precisely express the mathematical constraints you might have.\n\n### Variable to Constant (evaluation)\nLet's have a look at one of the simplest scenario:\n\nUsing the special Unicode char `≔` (single character for `:=` often used in literature for `assignment` of value.) we can write evaluations as:\n```swift\n𝑦² - 𝑥³.evaluate() {[ x ≔ 1, y ≔ 2 ]} \n```\n\nInstead of:\n```swift\n𝑦² - 𝑥³.evaluate() {[ x \u003c- 1, y \u003c- 2 ]} \n```\n\n### Complex examples\n\n Below is the example of how [`EllipticCurveKit`](https://github.com/Sajjon/EllipticCurveKit) uses `EquationKit` to express requirements on the elliptic curve parameters. Elliptic curves on the Weierstraß form requires this congruence inequality to hold:\n\n```math\n𝟜𝑎³ + 𝟚𝟟𝑏² ≢ 𝟘 mod 𝑝\n```\n\nThanks to `EquationKit` we can express said inequality almost identically to pure math in Swift:\n```swift\n𝟜𝑎³ + 𝟚𝟟𝑏² ≢ 0 % 𝑝 \n```\n\nBut that is not enough since we also need to evaluate said inequality (polynomial) using the arguments passed in the initializer. We can of course write\n```swift\n(𝟜𝑎³ + 𝟚𝟟𝑏²).evaluate(modulus: 𝑝) {[ 𝑎 ≔ a, 𝑏 ≔ b ]} != 0\n```\n\nBut a slightly more \"mathy\" syntax would be:\n```swift\n𝟜𝑎³ + 𝟚𝟟𝑏² ≢ 𝟘 % 𝑝 ↤ [ 𝑎 ≔ a, 𝑏 ≔ b ]\n```\n\n\nWhich evaluates the polynomial `𝟜𝑎³ + 𝟚𝟟𝑏²` given `a` and `b` and performs modulo `𝑝` and compares it to `0`. We could, of course, add support for this syntax as well:\n```swift\n// This syntax is not yet supported, but can easily be added\n[a→𝑎, b→𝑏] ⟼ 𝟜𝑎³ + 𝟚𝟟𝑏² ≢ 𝟘 % 𝑝\n```\n\nWe can of course also write this without using any special unicode char, like so:\n```swift\n4*a^^3 + 27*b^^2 =!%= 0 % p \u003c-- [ a ≔ constA, b ≔ constB ]\n```\nwhere `=!%=` replaces `≢`.\n\nPlease give feedback on the choice of operators, by [submitting an issue](https://github.com/Sajjon/EquationKit/issues/new).\n\n```swift\nlet 𝑎 = Variable(\"𝑎\")\nlet 𝑏 = Variable(\"𝑏\")\nlet 𝑎³ = Exponentiation(𝑎, exponent: 3)\nlet 𝑏² = Exponentiation(𝑏, exponent: 2)\n\nlet 𝟜𝑎³ = 4*𝑎³\nlet 𝟚𝟟𝑏² = 27*𝑏²\nlet 𝟘: BigInt = 0\n\n///\n/// Elliptic Curve on Short Weierstraß form (`𝑆`)\n/// - Covers all elliptic curves char≠𝟚,𝟛\n/// - Mixed Jacobian coordinates have been the speed leader for a long time.\n///\n///\n/// # Equation\n///      𝑆: 𝑦² = 𝑥³ + 𝑎𝑥 + 𝑏\n/// - Requires: `𝟜𝑎³ + 𝟚𝟟𝑏² ≠ 𝟘 in 𝔽_𝑝 (mod 𝑝)`\n///\nstruct ShortWeierstraßCurve {\n    /// Try to initialize an elliptic curve on the ShortWeierstraß form using parameters for `a`, `b` in the given Galois field (mod 𝑝).\n    public init(a: BigInt, b: BigInt, field 𝑝: BigInt) throws {\n        guard \n            𝟜𝑎³ + 𝟚𝟟𝑏² ≢ 𝟘 % 𝑝 ↤ [ 𝑎 ≔ a, 𝑏 ≔ b ]\n        else { throw EllipticCurveError.invalidCurveParameters }\n        self.a = a\n        self.b = b\n        self.field = 𝑝\n    }\n}\n```\n\n\n## Supported\n- Single and multivariate equations (no limitation to how many variables, go crazy!)\n- Differentiate any single or multivariate equation with respect to some of its variables\n- Multiply equations with equations\n- Modulus\n- BigInt support\n\n## Limitations\n\n### Not supported, but on roadmap\n- Substitution `(3*(4*x + 5)^^2 - 2*(4x+5) - 1).substitute() { z \u003c~ (4*x + 5) }` // `3*z²-2*z-1`  \n- Division\n- Finding roots (solving)\n\n\n### Not supported and not on the roadmap\n- Variables in exponents, such as `2^x`\n- `log`/`ln` functions\n- Trigonometric functions (`sin`, `cos`, `tan` etc.)\n- Complex numbers \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsajjon%2Fequationkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsajjon%2Fequationkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsajjon%2Fequationkit/lists"}