<commit_before>//
//  BezierCurve+Implicitization.swift
//  BezierKit
//
//  Created by <NAME> on 4/1/21.
//  Copyright © 2021 <NAME>. All rights reserved.
//

import Foundation

public protocol Implicitizeable {
    var implicitPolynomial: ImplicitPolynomial { get }
    var inverse: (numerator: ImplicitPolynomial, denominator: ImplicitPolynomial) { get }
}

public struct ImplicitPolynomial {

    fileprivate let coefficients: [CGFloat]
    public let order: Int

    fileprivate init(_ lineProduct: ImplicitLineProduct) {
        coefficients = [lineProduct.a00, lineProduct.a01, lineProduct.a02,
                        lineProduct.a10, lineProduct.a11, 0,
                        lineProduct.a20, 0, 0]
        order = 2
    }

    fileprivate init(_ line: ImplicitLine) {
        coefficients = [line.a00, line.a01, line.a10, 0]
        order = 1
    }

    init(coefficients: [CGFloat], order: Int) {
        assert(coefficients.count == (order + 1) * (order + 1))
        self.coefficients = coefficients
        self.order = order
    }

    /// get the coefficient aij for x^i y^j
    public func coefficient(_ i: Int, _ j: Int) -> CGFloat {
        assert(i >= 0 && i <= order && j >= 0 && j <= order)
        return coefficients[(order + 1) * i + j]
    }

    public func value(_ x: BernsteinPolynomialN, _ y: BernsteinPolynomialN) -> BernsteinPolynomialN {

        var xPowers: [BernsteinPolynomialN] = [BernsteinPolynomialN(coefficients: [1])]
        var yPowers: [BernsteinPolynomialN] = [BernsteinPolynomialN(coefficients: [1])]
        for i in 1...order {
            xPowers.append(xPowers[i - 1] * x)
            yPowers.append(yPowers[i - 1] * y)
        }

        let resultOrder = order * order
        var sum: BernsteinPolynomialN = BernsteinPolynomialN(coefficients: [CGFloat](repeating: 0, count: resultOrder + 1))
        for i in 0...order {
            let xPower: BernsteinPolynomialN = xPowers[i]
            for j in 0...order {

                let c: CGFloat = coefficient(i, j)
                guard c != 0 else { continue }

                let yPower: BernsteinPolynomialN = yPowers[j]

                let k = resultOrder - xPower.order - yPower.order

                var term: BernsteinPolynomialN = (xPower * yPower)

                // swiftlint:disable shorthand_operator
                if k > 0 {
                    // bring the term up to degree k
                    term = term * BernsteinPolynomialN(coefficients: [CGFloat](repeating: 1, count: k + 1))
                } else {
                    assert(k == 0, "for k < 0 we should have c == 0")<commit_msg>fixed logical error in result order.<commit_after>//
//  BezierCurve+Implicitization.swift
//  BezierKit
//
//  Created by <NAME> on 4/1/21.
//  Copyright © 2021 <NAME>. All rights reserved.
//

import Foundation

public protocol Implicitizeable {
    var implicitPolynomial: ImplicitPolynomial { get }
    var inverse: (numerator: ImplicitPolynomial, denominator: ImplicitPolynomial) { get }
}

public struct ImplicitPolynomial {

    fileprivate let coefficients: [CGFloat]
    public let order: Int

    fileprivate init(_ lineProduct: ImplicitLineProduct) {
        coefficients = [lineProduct.a00, lineProduct.a01, lineProduct.a02,
                        lineProduct.a10, lineProduct.a11, 0,
                        lineProduct.a20, 0, 0]
        order = 2
    }

    fileprivate init(_ line: ImplicitLine) {
        coefficients = [line.a00, line.a01, line.a10, 0]
        order = 1
    }

    init(coefficients: [CGFloat], order: Int) {
        assert(coefficients.count == (order + 1) * (order + 1))
        self.coefficients = coefficients
        self.order = order
    }

    /// get the coefficient aij for x^i y^j
    public func coefficient(_ i: Int, _ j: Int) -> CGFloat {
        assert(i >= 0 && i <= order && j >= 0 && j <= order)
        return coefficients[(order + 1) * i + j]
    }

    public func value(_ x: BernsteinPolynomialN, _ y: BernsteinPolynomialN) -> BernsteinPolynomialN {

        assert(x.order == y.order, "x and y coordinate polynomials must have same degree")
        let polynomialOrder = x.order
        var xPowers: [BernsteinPolynomialN] = [BernsteinPolynomialN(coefficients: [1])]
        var yPowers: [BernsteinPolynomialN] = [BernsteinPolynomialN(coefficients: [1])]
        for i in 1...order {
            xPowers.append(xPowers[i - 1] * x)
            yPowers.append(yPowers[i - 1] * y)
        }

        let resultOrder = order * polynomialOrder
        var sum: BernsteinPolynomialN = BernsteinPolynomialN(coefficients: [CGFloat](repeating: 0, count: resultOrder + 1))
        for i in 0...order {
            let xPower: BernsteinPolynomialN = xPowers[i]
            for j in 0...order {

                let c: CGFloat = coefficient(i, j)
                guard c != 0 else { continue }

                let yPower: BernsteinPolynomialN = yPowers[j]

                let k = resultOrder - xPower.order - yPower.order

                var term: BernsteinPolynomialN = (xPower * yPower)

                // swiftlint:disable shorthand_operator
                if k > 0 {
                    // bring the term up to degree k
                    term = term * BernsteinPolynomialN(coefficients: [CGFloat](repeating: 1, count: k + 1))
                } else {
                    assert(k == 0, "for k < 0 we should have c == 0")
{'fraction_non_alphanumeric': 0.10530218761586949, 'fraction_numerical': 0.0196514645902855, 'mean_word_length': 2.1077188940092166, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6196580', 'n_tokens_mistral': 1780, 'n_tokens_neox': 1598, 'n_words': 454}