text:
int_rules_4_7_7 = @theory begin

    #= ::Subsection::Closed:: =#
    #= 4.7.7*F^(c*(a+b*x))*trig(d+e*x)^n =#
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * sin(~(d') + ~(e') * ~x), ~x) => (~b * ~c * log(~F) * (~F) ^ (~c * (~a + ~b * ~x)) * sin(~d + ~e * ~x)) / ((~e) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2) - (~e * (~F) ^ (~c * (~a + ~b * ~x)) * cos(~d + ~e * ~x)) / ((~e) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e], ~x) && NeQ((~e) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2, 0)
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * cos(~(d') + ~(e') * ~x), ~x) => (~b * ~c * log(~F) * (~F) ^ (~c * (~a + ~b * ~x)) * cos(~d + ~e * ~x)) / ((~e) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2) + (~e * (~F) ^ (~c * (~a + ~b * ~x)) * sin(~d + ~e * ~x)) / ((~e) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e], ~x) && NeQ((~e) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2, 0)
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * sin(~(d') + ~(e') * ~x) ^ ~n, ~x) => ((~b * ~c * log(~F) * (~F) ^ (~c * (~a + ~b * ~x)) * sin(~d + ~e * ~x) ^ ~n) / ((~e) ^ 2 * (~n) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2) - (~e * ~n * (~F) ^ (~c * (~a + ~b * ~x)) * cos(~d + ~e * ~x) * sin(~d + ~e * ~x) ^ (~n - 1)) / ((~e) ^ 2 * (~n) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2)) + ((~n * (~n - 1) * (~e) ^ 2) / ((~e) ^ 2 * (~n) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2)) * Antiderivative((~F) ^ (~c * (~a + ~b * ~x)) * sin(~d + ~e * ~x) ^ (~n - 2), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e], ~x) && (NeQ((~e) ^ 2 * (~n) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2, 0) && GtQ(~n, 1))
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * cos(~(d') + ~(e') * ~x) ^ ~m, ~x) => (~b * ~c * log(~F) * (~F) ^ (~c * (~a + ~b * ~x)) * cos(~d + ~e * ~x) ^ ~m) / ((~e) ^ 2 * (~m) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2) + (~e * ~m * (~F) ^ (~c * (~a + ~b * ~x)) * sin(~d + ~e * ~x) * cos(~d + ~e * ~x) ^ (~m - 1)) / ((~e) ^ 2 * (~m) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2) + ((~m * (~m - 1) * (~e) ^ 2) / ((~e) ^ 2 * (~m) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2)) * Antiderivative((~F) ^ (~c * (~a + ~b * ~x)) * cos(~d + ~e * ~x) ^ (~m - 2), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e], ~x) && (NeQ((~e) ^ 2 * (~m) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2, 0) && GtQ(~m, 1))
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * sin(~(d') + ~(e') * ~x) ^ ~n, ~x) => (-(~b) * ~c * log(~F) * (~F) ^ (~c * (~a + ~b * ~x)) * sin(~d + ~e * ~x) ^ (~n + 2)) / ((~e) ^ 2 * (~n + 1) * (~n + 2)) + ((~F) ^ (~c * (~a + ~b * ~x)) * cos(~d + ~e * ~x) * sin(~d + ~e * ~x) ^ (~n + 1)) / (~e * (~n + 1)) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e, ~n], ~x) && (EqQ((~e) ^ 2 * (~n + 2) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2, 0) && (NeQ(~n, -1) && NeQ(~n, -2)))
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * cos(~(d') + ~(e') * ~x) ^ ~n, ~x) => (-(~b) * ~c * log(~F) * (~F) ^ (~c * (~a + ~b * ~x)) * cos(~d + ~e * ~x) ^ (~n + 2)) / ((~e) ^ 2 * (~n + 1) * (~n + 2)) - ((~F) ^ (~c * (~a + ~b * ~x)) * sin(~d + ~e * ~x) * cos(~d + ~e * ~x) ^ (~n + 1)) / (~e * (~n + 1)) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e, ~n], ~x) && (EqQ((~e) ^ 2 * (~n + 2) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2, 0) && (NeQ(~n, -1) && NeQ(~n, -2)))
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * sin(~(d') + ~(e') * ~x) ^ ~n, ~x) => (-(~b) * ~c * log(~F) * (~F) ^ (~c * (~a + ~b * ~x)) * sin(~d + ~e * ~x) ^ (~n + 2)) / ((~e) ^ 2 * (~n + 1) * (~n + 2)) + ((~F) ^ (~c * (~a + ~b * ~x)) * cos(~d + ~e * ~x) * sin(~d + ~e * ~x) ^ (~n + 1)) / (~e * (~n + 1)) + (((~e) ^ 2 * (~n + 2) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2) / ((~e) ^ 2 * (~n + 1) * (~n + 2))) * Antiderivative((~F) ^ (~c * (~a + ~b * ~x)) * sin(~d + ~e * ~x) ^ (~n + 2), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e], ~x) && (NeQ((~e) ^ 2 * (~n + 2) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2, 0) && (LtQ(~n, -1) && NeQ(~n, -2)))
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * cos(~(d') + ~(e') * ~x) ^ ~n, ~x) => ((-(~b) * ~c * log(~F) * (~F) ^ (~c * (~a + ~b * ~x)) * cos(~d + ~e * ~x) ^ (~n + 2)) / ((~e) ^ 2 * (~n + 1) * (~n + 2)) - ((~F) ^ (~c * (~a + ~b * ~x)) * sin(~d + ~e * ~x) * cos(~d + ~e * ~x) ^ (~n + 1)) / (~e * (~n + 1))) + (((~e) ^ 2 * (~n + 2) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2) / ((~e) ^ 2 * (~n + 1) * (~n + 2))) * Antiderivative((~F) ^ (~c * (~a + ~b * ~x)) * cos(~d + ~e * ~x) ^ (~n + 2), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e], ~x) && (NeQ((~e) ^ 2 * (~n + 2) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2, 0) && (LtQ(~n, -1) && NeQ(~n, -2)))
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * sin(~(d') + ~(e') * ~x) ^ ~n, ~x) => ((ℯ ^ (im * ~n * (~d + ~e * ~x)) * sin(~d + ~e * ~x) ^ ~n) / (-1 + ℯ ^ (2 * im * (~d + ~e * ~x))) ^ ~n) * Antiderivative(((~F) ^ (~c * (~a + ~b * ~x)) * (-1 + ℯ ^ (2 * im * (~d + ~e * ~x))) ^ ~n) / ℯ ^ (im * ~n * (~d + ~e * ~x)), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e, ~n], ~x) && Not(IntegerQ(~n))
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * cos(~(d') + ~(e') * ~x) ^ ~n, ~x) => ((ℯ ^ (im * ~n * (~d + ~e * ~x)) * cos(~d + ~e * ~x) ^ ~n) / (1 + ℯ ^ (2 * im * (~d + ~e * ~x))) ^ ~n) * Antiderivative(((~F) ^ (~c * (~a + ~b * ~x)) * (1 + ℯ ^ (2 * im * (~d + ~e * ~x))) ^ ~n) / ℯ ^ (im * ~n * (~d + ~e * ~x)), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e, ~n], ~x) && Not(IntegerQ(~n))
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * tan(~(d') + ~(e') * ~x) ^ ~(n'), ~x) => im ^ ~n * Antiderivative(ExpandIntegrand(((~F) ^ (~c * (~a + ~b * ~x)) * (1 - ℯ ^ (2 * im * (~d + ~e * ~x))) ^ ~n) / (1 + ℯ ^ (2 * im * (~d + ~e * ~x))) ^ ~n, ~x), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e], ~x) && IntegerQ(~n)
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * cot(~(d') + ~(e') * ~x) ^ ~(n'), ~x) => (-im) ^ ~n * Antiderivative(ExpandIntegrand(((~F) ^ (~c * (~a + ~b * ~x)) * (1 + ℯ ^ (2 * im * (~d + ~e * ~x))) ^ ~n) / (1 - ℯ ^ (2 * im * (~d + ~e * ~x))) ^ ~n, ~x), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e], ~x) && IntegerQ(~n)
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * sec(~(d') + ~(e') * ~x) ^ ~n, ~x) => (~b * ~c * log(~F) * (~F) ^ (~c * (~a + ~b * ~x)) * (sec(~d + ~e * ~x) ^ ~n / ((~e) ^ 2 * (~n) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2)) - ~e * ~n * (~F) ^ (~c * (~a + ~b * ~x)) * sec(~d + ~e * ~x) ^ (~n + 1) * (sin(~d + ~e * ~x) / ((~e) ^ 2 * (~n) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2))) + (~e) ^ 2 * ~n * ((~n + 1) / ((~e) ^ 2 * (~n) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2)) * Antiderivative((~F) ^ (~c * (~a + ~b * ~x)) * sec(~d + ~e * ~x) ^ (~n + 2), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e], ~x) && (NeQ((~e) ^ 2 * (~n) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2, 0) && LtQ(~n, -1))
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * csc(~(d') + ~(e') * ~x) ^ ~n, ~x) => ~b * ~c * log(~F) * (~F) ^ (~c * (~a + ~b * ~x)) * (csc(~d + ~e * ~x) ^ ~n / ((~e) ^ 2 * (~n) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2)) + ~e * ~n * (~F) ^ (~c * (~a + ~b * ~x)) * csc(~d + ~e * ~x) ^ (~n + 1) * (cos(~d + ~e * ~x) / ((~e) ^ 2 * (~n) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2)) + (~e) ^ 2 * ~n * ((~n + 1) / ((~e) ^ 2 * (~n) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2)) * Antiderivative((~F) ^ (~c * (~a + ~b * ~x)) * csc(~d + ~e * ~x) ^ (~n + 2), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e], ~x) && (NeQ((~e) ^ 2 * (~n) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2, 0) && LtQ(~n, -1))
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * sec(~(d') + ~(e') * ~x) ^ ~n, ~x) => (-(~b) * ~c * log(~F) * (~F) ^ (~c * (~a + ~b * ~x)) * sec(~d + ~e * ~x) ^ (~n - 2)) / ((~e) ^ 2 * (~n - 1) * (~n - 2)) + ((~F) ^ (~c * (~a + ~b * ~x)) * sec(~d + ~e * ~x) ^ (~n - 1) * sin(~d + ~e * ~x)) / (~e * (~n - 1)) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e, ~n], ~x) && (EqQ((~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2 + (~e) ^ 2 * (~n - 2) ^ 2, 0) && (NeQ(~n, 1) && NeQ(~n, 2)))
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * csc(~(d') + ~(e') * ~x) ^ ~n, ~x) => (-(~b) * ~c * log(~F) * (~F) ^ (~c * (~a + ~b * ~x)) * csc(~d + ~e * ~x) ^ (~n - 2)) / ((~e) ^ 2 * (~n - 1) * (~n - 2)) + ((~F) ^ (~c * (~a + ~b * ~x)) * csc(~d + ~e * ~x) ^ (~n - 1) * cos(~d + ~e * ~x)) / (~e * (~n - 1)) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e, ~n], ~x) && (EqQ((~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2 + (~e) ^ 2 * (~n - 2) ^ 2, 0) && (NeQ(~n, 1) && NeQ(~n, 2)))
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * sec(~(d') + ~(e') * ~x) ^ ~n, ~x) => (-(~b) * ~c * log(~F) * (~F) ^ (~c * (~a + ~b * ~x)) * sec(~d + ~e * ~x) ^ (~n - 2)) / ((~e) ^ 2 * (~n - 1) * (~n - 2)) + ((~F) ^ (~c * (~a + ~b * ~x)) * sec(~d + ~e * ~x) ^ (~n - 1) * sin(~d + ~e * ~x)) / (~e * (~n - 1)) + (((~e) ^ 2 * (~n - 2) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2) / ((~e) ^ 2 * (~n - 1) * (~n - 2))) * Antiderivative((~F) ^ (~c * (~a + ~b * ~x)) * sec(~d + ~e * ~x) ^ (~n - 2), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e], ~x) && (NeQ((~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2 + (~e) ^ 2 * (~n - 2) ^ 2, 0) && (GtQ(~n, 1) && NeQ(~n, 2)))
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * csc(~(d') + ~(e') * ~x) ^ ~n, ~x) => ((-(~b) * ~c * log(~F) * (~F) ^ (~c * (~a + ~b * ~x)) * csc(~d + ~e * ~x) ^ (~n - 2)) / ((~e) ^ 2 * (~n - 1) * (~n - 2)) - ((~F) ^ (~c * (~a + ~b * ~x)) * csc(~d + ~e * ~x) ^ (~n - 1) * cos(~d + ~e * ~x)) / (~e * (~n - 1))) + (((~e) ^ 2 * (~n - 2) ^ 2 + (~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2) / ((~e) ^ 2 * (~n - 1) * (~n - 2))) * Antiderivative((~F) ^ (~c * (~a + ~b * ~x)) * csc(~d + ~e * ~x) ^ (~n - 2), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e], ~x) && (NeQ((~b) ^ 2 * (~c) ^ 2 * log(~F) ^ 2 + (~e) ^ 2 * (~n - 2) ^ 2, 0) && (GtQ(~n, 1) && NeQ(~n, 2)))
    #= Antiderivative((~F)^((~c')*((~a')+(~b')*(~x)))*sec((~d')+(~e')*(~x))^(~n'),~x) :=  2^n*Antiderivative(SimplifyIntegrand(F^(c*(a+b*x))*ℯ^(im*n*(d+e*x))/(1+ℯ^(2*im*(d+ e*x)))^n,x),x) <-- FreeQ([F,a,b,c,d,e],x) && IntegerQ(n) =#
    #= Antiderivative((~F)^((~c')*((~a')+(~b')*(~x)))*csc((~d')+(~e')*(~x))^(~n'),~x) :=  (2*im)^n*Antiderivative(SimplifyIntegrand(F^(c*(a+b*x))*ℯ^(-im*n*(d+e*x))/(1-ℯ^(-2* im*(d+e*x)))^n,x),x) <-- FreeQ([F,a,b,c,d,e],x) && IntegerQ(n) =#
    # Missing due to parse error: Antiderivative((~F)^((~c')*((~a') + (~b')*(~x)))*sec((~d') + (~k')*pi + (~e')*(~x))^(~n'), ~x) := 2^n*ℯ^(im*k*n*pi)*ℯ^(im*n*(d + e*x))* F^(c*(a + b*x))/(im*e*n + b*c*log(F))* HypergeometricFunctions._₂F₁(n, n/2 - im*b*c*log(F)/(2*e), 1 + n/2 - im*b*c*log(F)/(2*e), -ℯ^(2*im*k*pi)*ℯ^(2*im*(d + e*x))) <-- FreeQ([F, a, b, c, d, e], x) && IntegerQ(4*k) && IntegerQ(n)
    # Missing due to parse error: Antiderivative((~F)^((~c')*((~a') + (~b')*(~x)))*sec((~d') + (~e')*(~x))^(~n'), ~x) := 2^n*ℯ^(im*n*(d + e*x))*F^(c*(a + b*x))/(im*e*n + b*c*log(F))* HypergeometricFunctions._₂F₁(n, n/2 - im*b*c*log(F)/(2*e), 1 + n/2 - im*b*c*log(F)/(2*e), -ℯ^(2*im*(d + e*x))) <-- FreeQ([F, a, b, c, d, e], x) && IntegerQ(n)
    # Missing due to parse error: Antiderivative((~F)^((~c')*((~a') + (~b')*(~x)))*csc((~d') + (~k')*pi + (~e')*(~x))^(~n'), ~x) := (-2*im)^n*ℯ^(im*k*n*pi)* ℯ^(im*n*(d + e*x))*(F^(c*(a + b*x))/(im*e*n + b*c*log(F)))* HypergeometricFunctions._₂F₁(n, n/2 - im*b*c*log(F)/(2*e), 1 + n/2 - im*b*c*log(F)/(2*e), ℯ^(2*im*k*pi)*ℯ^(2*im*(d + e*x))) <-- FreeQ([F, a, b, c, d, e], x) && IntegerQ(4*k) && IntegerQ(n)
    # Missing due to parse error: Antiderivative((~F)^((~c')*((~a') + (~b')*(~x)))*csc((~d') + (~e')*(~x))^(~n'), ~x) := (-2*im)^n* ℯ^(im*n*(d + e*x))*(F^(c*(a + b*x))/(im*e*n + b*c*log(F)))* HypergeometricFunctions._₂F₁(n, n/2 - im*b*c*log(F)/(2*e), 1 + n/2 - im*b*c*log(F)/(2*e), ℯ^(2*im*(d + e*x))) <-- FreeQ([F, a, b, c, d, e], x) && IntegerQ(n)
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * sec(~(d') + ~(e') * ~x) ^ ~(n'), ~x) => (((1 + ℯ ^ (2 * im * (~d + ~e * ~x))) ^ ~n * sec(~d + ~e * ~x) ^ ~n) / ℯ ^ (im * ~n * (~d + ~e * ~x))) * Antiderivative(SimplifyIntegrand(((~F) ^ (~c * (~a + ~b * ~x)) * ℯ ^ (im * ~n * (~d + ~e * ~x))) / (1 + ℯ ^ (2 * im * (~d + ~e * ~x))) ^ ~n, ~x), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e], ~x) && Not(IntegerQ(~n))
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * csc(~(d') + ~(e') * ~x) ^ ~(n'), ~x) => (((1 - ℯ ^ (-2 * im * (~d + ~e * ~x))) ^ ~n * csc(~d + ~e * ~x) ^ ~n) / ℯ ^ (-im * ~n * (~d + ~e * ~x))) * Antiderivative(SimplifyIntegrand(((~F) ^ (~c * (~a + ~b * ~x)) * ℯ ^ (-im * ~n * (~d + ~e * ~x))) / (1 - ℯ ^ (-2 * im * (~d + ~e * ~x))) ^ ~n, ~x), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e], ~x) && Not(IntegerQ(~n))
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * (~f + ~(g') * sin(~(d') + ~(e') * ~x)) ^ ~(n'), ~x) => 2 ^ ~n * (~f) ^ ~n * Antiderivative((~F) ^ (~c * (~a + ~b * ~x)) * cos((~d / 2 - (~f * pi) / (4 * ~g)) + (~e * ~x) / 2) ^ (2 * ~n), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e, ~f, ~g], ~x) && (EqQ((~f) ^ 2 - (~g) ^ 2, 0) && ILtQ(~n, 0))
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * (~f + ~(g') * cos(~(d') + ~(e') * ~x)) ^ ~(n'), ~x) => 2 ^ ~n * (~f) ^ ~n * Antiderivative((~F) ^ (~c * (~a + ~b * ~x)) * cos(~d / 2 + (~e * ~x) / 2) ^ (2 * ~n), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e, ~f, ~g], ~x) && (EqQ(~f - ~g, 0) && ILtQ(~n, 0))
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * (~f + ~(g') * cos(~(d') + ~(e') * ~x)) ^ ~(n'), ~x) => 2 ^ ~n * (~f) ^ ~n * Antiderivative((~F) ^ (~c * (~a + ~b * ~x)) * sin(~d / 2 + (~e * ~x) / 2) ^ (2 * ~n), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e, ~f, ~g], ~x) && (EqQ(~f + ~g, 0) && ILtQ(~n, 0))
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * (~f + ~(g') * sin(~(d') + ~(e') * ~x)) ^ ~(n'), ~x) => ((~f + ~g * sin(~d + ~e * ~x)) ^ ~n / cos((~d / 2 - (~f * pi) / (4 * ~g)) + (~e * ~x) / 2) ^ (2 * ~n)) * Antiderivative((~F) ^ (~c * (~a + ~b * ~x)) * cos((~d / 2 - (~f * pi) / (4 * ~g)) + (~e * ~x) / 2) ^ (2 * ~n), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e, ~f, ~g, ~n], ~x) && (EqQ((~f) ^ 2 - (~g) ^ 2, 0) && Not(IntegerQ(~n)))
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * (~f + ~(g') * cos(~(d') + ~(e') * ~x)) ^ ~(n'), ~x) => ((~f + ~g * cos(~d + ~e * ~x)) ^ ~n / cos(~d / 2 + (~e * ~x) / 2) ^ (2 * ~n)) * Antiderivative((~F) ^ (~c * (~a + ~b * ~x)) * cos(~d / 2 + (~e * ~x) / 2) ^ (2 * ~n), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e, ~f, ~g, ~n], ~x) && (EqQ(~f - ~g, 0) && Not(IntegerQ(~n)))
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * (~f + ~(g') * cos(~(d') + ~(e') * ~x)) ^ ~(n'), ~x) => ((~f + ~g * cos(~d + ~e * ~x)) ^ ~n / sin(~d / 2 + (~e * ~x) / 2) ^ (2 * ~n)) * Antiderivative((~F) ^ (~c * (~a + ~b * ~x)) * sin(~d / 2 + (~e * ~x) / 2) ^ (2 * ~n), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e, ~f, ~g, ~n], ~x) && (EqQ(~f + ~g, 0) && Not(IntegerQ(~n)))
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * cos(~(d') + ~(e') * ~x) ^ ~(m') * (~f + ~(g') * sin(~(d') + ~(e') * ~x)) ^ ~(n'), ~x) => (~g) ^ ~n * Antiderivative((~F) ^ (~c * (~a + ~b * ~x)) * tan(((~f * pi) / (4 * ~g) - ~d / 2) - (~e * ~x) / 2) ^ ~m, ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e, ~f, ~g], ~x) && (EqQ((~f) ^ 2 - (~g) ^ 2, 0) && (IntegersQ(~m, ~n) && EqQ(~m + ~n, 0)))
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * sin(~(d') + ~(e') * ~x) ^ ~(m') * (~f + ~(g') * cos(~(d') + ~(e') * ~x)) ^ ~(n'), ~x) => (~f) ^ ~n * Antiderivative((~F) ^ (~c * (~a + ~b * ~x)) * tan(~d / 2 + (~e * ~x) / 2) ^ ~m, ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e, ~f, ~g], ~x) && (EqQ(~f - ~g, 0) && (IntegersQ(~m, ~n) && EqQ(~m + ~n, 0)))
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * sin(~(d') + ~(e') * ~x) ^ ~(m') * (~f + ~(g') * cos(~(d') + ~(e') * ~x)) ^ ~(n'), ~x) => (~f) ^ ~n * Antiderivative((~F) ^ (~c * (~a + ~b * ~x)) * cot(~d / 2 + (~e * ~x) / 2) ^ ~m, ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e, ~f, ~g], ~x) && (EqQ(~f + ~g, 0) && (IntegersQ(~m, ~n) && EqQ(~m + ~n, 0)))
    @apply_utils Antiderivative(((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * (~h + ~(i') * cos(~(d') + ~(e') * ~x))) / (~f + ~(g') * sin(~(d') + ~(e') * ~x)), ~x) => 2 * ~i * Antiderivative((~F) ^ (~c * (~a + ~b * ~x)) * (cos(~d + ~e * ~x) / (~f + ~g * sin(~d + ~e * ~x))), ~x) + Antiderivative((~F) ^ (~c * (~a + ~b * ~x)) * ((~h - ~i * cos(~d + ~e * ~x)) / (~f + ~g * sin(~d + ~e * ~x))), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e, ~f, ~g, ~h, ~i], ~x) && (EqQ((~f) ^ 2 - (~g) ^ 2, 0) && (EqQ((~h) ^ 2 - (~i) ^ 2, 0) && EqQ(~g * ~h - ~f * ~i, 0)))
    @apply_utils Antiderivative(((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * (~h + ~(i') * sin(~(d') + ~(e') * ~x))) / (~f + ~(g') * cos(~(d') + ~(e') * ~x)), ~x) => 2 * ~i * Antiderivative((~F) ^ (~c * (~a + ~b * ~x)) * (sin(~d + ~e * ~x) / (~f + ~g * cos(~d + ~e * ~x))), ~x) + Antiderivative((~F) ^ (~c * (~a + ~b * ~x)) * ((~h - ~i * sin(~d + ~e * ~x)) / (~f + ~g * cos(~d + ~e * ~x))), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e, ~f, ~g, ~h, ~i], ~x) && (EqQ((~f) ^ 2 - (~g) ^ 2, 0) && (EqQ((~h) ^ 2 - (~i) ^ 2, 0) && EqQ(~g * ~h + ~f * ~i, 0)))
    @apply_utils Antiderivative((~F) ^ (~(c') * ~u) * (~G)(~v) ^ ~(n'), ~x) => Antiderivative((~F) ^ (~c * ExpandToSum(~u, ~x)) * (~G)(ExpandToSum(~v, ~x)) ^ ~n, ~x) <-- FreeQ([~F, ~c, ~n], ~x) && (TrigQ(~G) && (LinearQ([~u, ~v], ~x) && Not(LinearMatchQ([~u, ~v], ~x))))
    @apply_utils Antiderivative((~(f') * ~x) ^ ~(m') * (~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * sin(~(d') + ~(e') * ~x) ^ ~(n'), ~x) => Module([u = IntHide((~F) ^ (~c * (~a + ~b * ~x)) * sin(~d + ~e * ~x) ^ ~n, ~x)], Dist((~f * ~x) ^ ~m, u, ~x) - ~f * ~m * Antiderivative((~f * ~x) ^ (~m - 1) * u, ~x)) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e, ~f], ~x) && (IGtQ(~n, 0) && GtQ(~m, 0))
    @apply_utils Antiderivative((~(f') * ~x) ^ ~(m') * (~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * cos(~(d') + ~(e') * ~x) ^ ~(n'), ~x) => Module([u = IntHide((~F) ^ (~c * (~a + ~b * ~x)) * cos(~d + ~e * ~x) ^ ~n, ~x)], Dist((~f * ~x) ^ ~m, u, ~x) - ~f * ~m * Antiderivative((~f * ~x) ^ (~m - 1) * u, ~x)) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e, ~f], ~x) && (IGtQ(~n, 0) && GtQ(~m, 0))
    @apply_utils Antiderivative((~(f') * ~x) ^ ~m * (~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * sin(~(d') + ~(e') * ~x), ~x) => (((~f * ~x) ^ (~m + 1) / (~f * (~m + 1))) * (~F) ^ (~c * (~a + ~b * ~x)) * sin(~d + ~e * ~x) - (~e / (~f * (~m + 1))) * Antiderivative((~f * ~x) ^ (~m + 1) * (~F) ^ (~c * (~a + ~b * ~x)) * cos(~d + ~e * ~x), ~x)) - ((~b * ~c * log(~F)) / (~f * (~m + 1))) * Antiderivative((~f * ~x) ^ (~m + 1) * (~F) ^ (~c * (~a + ~b * ~x)) * sin(~d + ~e * ~x), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e, ~f, ~m], ~x) && (LtQ(~m, -1) || SumSimplerQ(~m, 1))
    @apply_utils Antiderivative((~(f') * ~x) ^ ~m * (~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * cos(~(d') + ~(e') * ~x), ~x) => (((~f * ~x) ^ (~m + 1) / (~f * (~m + 1))) * (~F) ^ (~c * (~a + ~b * ~x)) * cos(~d + ~e * ~x) + (~e / (~f * (~m + 1))) * Antiderivative((~f * ~x) ^ (~m + 1) * (~F) ^ (~c * (~a + ~b * ~x)) * sin(~d + ~e * ~x), ~x)) - ((~b * ~c * log(~F)) / (~f * (~m + 1))) * Antiderivative((~f * ~x) ^ (~m + 1) * (~F) ^ (~c * (~a + ~b * ~x)) * cos(~d + ~e * ~x), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e, ~f, ~m], ~x) && (LtQ(~m, -1) || SumSimplerQ(~m, 1))
    #= Antiderivative(((~f')*(~x))^(~m')*(~F)^((~c')*((~a')+(~b')*(~x)))*sin((~d')+(~e')*(~x))^(~n'),(~x)*Symbol) :=  im^n/2^n*Antiderivative(ExpandIntegrand((f*x)^m*F^(c*(a+b*x)),(ℯ^(-im*(d+e*x))-ℯ^( im*(d+e*x)))^n,x),x) <-- FreeQ([F,a,b,c,d,e,f],x) && IGtQ(n,0) =#
    #= Antiderivative(((~f')*(~x))^(~m')*(~F)^((~c')*((~a')+(~b')*(~x)))*cos((~d')+(~e')*(~x))^(~n'),(~x)*Symbol) :=  1/2^n*Antiderivative(ExpandIntegrand((f*x)^m*F^(c*(a+b*x)),(ℯ^(-im*(d+e*x))+ℯ^(im*( d+e*x)))^n,x),x) <-- FreeQ([F,a,b,c,d,e,f],x) && IGtQ(n,0) =#
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * sin(~(d') + ~(e') * ~x) ^ ~(m') * cos(~(f') + ~(g') * ~x) ^ ~(n'), ~x) => Antiderivative(ExpandTrigReduce((~F) ^ (~c * (~a + ~b * ~x)), sin(~d + ~e * ~x) ^ ~m * cos(~f + ~g * ~x) ^ ~n, ~x), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e, ~f, ~g], ~x) && (IGtQ(~m, 0) && IGtQ(~n, 0))
    @apply_utils Antiderivative((~x) ^ ~(p') * (~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * sin(~(d') + ~(e') * ~x) ^ ~(m') * cos(~(f') + ~(g') * ~x) ^ ~(n'), ~x) => Antiderivative(ExpandTrigReduce((~x) ^ ~p * (~F) ^ (~c * (~a + ~b * ~x)), sin(~d + ~e * ~x) ^ ~m * cos(~f + ~g * ~x) ^ ~n, ~x), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e, ~f, ~g], ~x) && (IGtQ(~m, 0) && (IGtQ(~n, 0) && IGtQ(~p, 0)))
    @apply_utils Antiderivative((~F) ^ (~(c') * (~(a') + ~(b') * ~x)) * (~G)(~(d') + ~(e') * ~x) ^ ~(m') * (~H)(~(d') + ~(e') * ~x) ^ ~(n'), ~x) => Antiderivative(ExpandTrigToExp((~F) ^ (~c * (~a + ~b * ~x)), (~G)(~d + ~e * ~x) ^ ~m * (~H)(~d + ~e * ~x) ^ ~n, ~x), ~x) <-- FreeQ([~F, ~a, ~b, ~c, ~d, ~e], ~x) && (IGtQ(~m, 0) && (IGtQ(~n, 0) && (TrigQ(~G) && TrigQ(~H))))
    @apply_utils Antiderivative((~F) ^ ~u * sin(~v) ^ ~(n'), ~x) => Antiderivative(ExpandTrigToExp((~F) ^ ~u, sin(~v) ^ ~n, ~x), ~x) <-- FreeQ(~F, ~x) && ((LinearQ(~u, ~x) || PolyQ(~u, ~x, 2)) && ((LinearQ(~v, ~x) || PolyQ(~v, ~x, 2)) && IGtQ(~n, 0)))
    @apply_utils Antiderivative((~F) ^ ~u * cos(~v) ^ ~(n'), ~x) => Antiderivative(ExpandTrigToExp((~F) ^ ~u, cos(~v) ^ ~n, ~x), ~x) <-- FreeQ(~F, ~x) && ((LinearQ(~u, ~x) || PolyQ(~u, ~x, 2)) && ((LinearQ(~v, ~x) || PolyQ(~v, ~x, 2)) && IGtQ(~n, 0)))
    @apply_utils Antiderivative((~F) ^ ~u * sin(~v) ^ ~(m') * cos(~v) ^ ~(n'), ~x) => Antiderivative(ExpandTrigToExp((~F) ^ ~u, sin(~v) ^ ~m * cos(~v) ^ ~n, ~x), ~x) <-- FreeQ(~F, ~x) && ((LinearQ(~u, ~x) || PolyQ(~u, ~x, 2)) && ((LinearQ(~v, ~x) || PolyQ(~v, ~x, 2)) && (IGtQ(~m, 0) && IGtQ(~n, 0))))
end

max_stars_repo_path: src/rules/4 Trig functions/4.7 Miscellaneous/4.7.7 F^(c (a+b x)) trig(d+e x)^n.jl


text:
include("../utils.jl")
include("group_utils.jl")

@testset "Product group" begin
    SOn = SpecialOrthogonal(3)
    Tn = TranslationGroup(2)
    Rn = Rotations(3)
    M = ProductManifold(SOn, Tn)
    G = ProductGroup(M)
    @test G isa ProductGroup
    @test base_manifold(G) === M
    @test repr(G) == "ProductGroup($(SOn), $(Tn))"
    x = Matrix{Float64}(I, 3, 3)

    t = Vector{Float64}.([1:2, 2:3, 3:4])
    ω = [[1.0, 2.0, 3.0], [3.0, 2.0, 1.0], [1.0, 3.0, 2.0]]
    tuple_pts = [(exp(Rn, x, hat(Rn, x, ωi)), ti) for (ωi, ti) in zip(ω, t)]
    tuple_v = (hat(Rn, x, [1.0, 0.5, -0.5]), [-1.0, 2.0])

    @testset "identity specializations" begin
        @test inv(G, Identity(G)) === Identity(G)
        @test identity(G, Identity(G)) === Identity(G)
        @test submanifold_component(G, Identity(G), Val(1)) === Identity(SOn)
        @test submanifold_component(G, Identity(G), Val(2)) === Identity(Tn)
        @test submanifold_components(G, Identity(G)) == (Identity(SOn), Identity(Tn))
        @test compose(G, Identity(G), Identity(G)) === Identity(G)
    end

    @testset "product point" begin
        reshapers = (Manifolds.ArrayReshaper(), Manifolds.StaticReshaper())
        for reshaper in reshapers
            shape_se = Manifolds.ShapeSpecification(reshaper, M.manifolds...)
            pts = [Manifolds.prod_point(shape_se, tp...) for tp in tuple_pts]
            v_pts = [Manifolds.prod_point(shape_se, tuple_v...)]
            @test compose(G, pts[1], Identity(G)) == pts[1]
            @test compose(G, Identity(G), pts[1]) == pts[1]
            test_group(G, pts, v_pts; test_diff = true)
        end
    end

    @testset "product repr" begin
        pts = [ProductRepr(tp...) for tp in tuple_pts]
        v_pts = [ProductRepr(tuple_v...)]
        @test compose(G, pts[1], Identity(G)) == pts[1]
        @test compose(G, Identity(G), pts[1]) == pts[1]
        test_group(G, pts, v_pts; test_diff = true, test_mutating = false)
    end
end

ext: jl


text:
module VariantsNMF

using Clustering
using DataFrames
using Distances
using Distributed
using Distributions
using LinearAlgebra: diag, norm, svd, transpose
using LinearAlgebra.BLAS: dot
using Printf: @printf
using ProgressMeter
using Random
using Statistics: mean, cor

export β_divergence
export α_divergence

#### common
export NMFMetrics
export NMF
export NMFParams
export NMFResults
export NMFSolver
export initialize_nmf

include("aux/structs.jl")
include("aux/clustering.jl")
include("aux/convergence.jl")
include("aux/divergences.jl")
include("aux/initialize.jl")
include("aux/scale.jl")

### cichocki_09
export CParams
export nmf_α

include("solver/cichocki_09/params.jl")
include("solver/cichocki_09/cost.jl")
include("solver/cichocki_09/nmf_alpha.jl")

#### base MU, FI
export MUParams
export FIParams
export nmf_MU
export nmf_FI

include("solver/base/nmf_MU.jl")
include("solver/base/nmf_FI.jl")

####
#### rank
####

#### stability: alexandrov et al
export RSParams
export RSNMFResults
export rank_by_stability

include("rank/stability/bootstrap.jl")
include("rank/stability/evaluate_stability.jl")
include("rank/stability/evaluate_fidelity.jl")
include("rank/stability/rank_by_stability.jl")

#### consensus: brunet et al
export RCParams
export RCNMFResults
export rank_by_consensus

include("rank/consensus/consensus_metrics.jl")
include("rank/consensus/rank_by_consensus.jl")

end


text:
export partialtrace

# We compute the partial trace of x by summing over
# (I ⊗ <j| ⊗ I) x (I ⊗ |j> ⊗ I) for all j's
# in the system we want to trace out.
# This function returns the jth term in the sum, namely
# (I ⊗ <j| ⊗ I) x (I ⊗ |j> ⊗ I).
function _term(x, j::Int, sys, dims)
    a = sparse(1.0I, 1, 1)
    b = sparse(1.0I, 1, 1)
    for (i_sys, dim) in enumerate(dims)
        if i_sys == sys
            # create a vector that is only 1 at its jth component
            v = spzeros(dim, 1);
            v[j] = 1;
            a = kron(a, v')
            b = kron(b, v)
        else
            a = kron(a, sparse(1.0I, dim, dim))
            b = kron(b, sparse(1.0I, dim, dim))
        end
    end
    return a * x * b
end

"""
    partialtrace(x, sys::Int, dims::Vector)

Returns the partial trace of `x` over the `sys`th system, where `dims` is a vector of integers encoding the dimensions of each subsystem.
"""
function partialtrace(x, sys::Int, dims::Vector)
    if size(x, 1) ≠ size(x, 2)
        throw(ArgumentError("Only square matrices are supported"))
    end
    if ! (1 ≤ sys ≤ length(dims))
        throw(ArgumentError("Invalid system index, should between 1 and $(length(dims)), got $sys"))
    end
    if size(x, 1) ≠ prod(dims)
        throw(ArgumentError("Dimension of system doesn't correspond to dimension of subsystems"))
    end

    return sum(j -> _term(x, j, sys, dims), 1:dims[sys])
end


text:
function get_evolution(obj::LinearProcess, arg0::Measurement)
    return jcall(obj, "getEvolution", LinearEvolution, (Measurement,), arg0)
end


text:
module EvalInModuleREPLMode

using REPL
using REPL.LineEdit

# default module
mod_name = "Main"
mod = Main
code = ""

# initialize prompts
module_selector_mode=LineEdit.Prompt("eval in module: ")
in_module_eval_mode=LineEdit.Prompt("Main")

function reset_module()
  global mod_name, mod
  mod_name = "Main"
  mod = Main
end

function return_callback(s)
  ast = Base.parse_input_line(String(take!(copy(LineEdit.buffer(s)))))
  if  !isa(ast, Expr) || (ast.head != :continue && ast.head != :incomplete)
      return true
  else
      return false
  end
end

function __init__()
  # setup prompts
  let main_mode = Base.active_repl.interface.modes[1]
    # setup keymap of both prompts
    module_selector_mode.keymap_dict = in_module_eval_mode.keymap_dict =
      LineEdit.keymap(Dict{Any,Any}[REPL.mode_keymap(main_mode),
        LineEdit.history_keymap, LineEdit.default_keymap,
        LineEdit.escape_defaults])

    module_selector_mode.on_enter = (s) -> begin
      global mod_name
      global mod
      buf = LineEdit.buffer(s)
      let new_name = String(take!(copy(buf))), is_except=false
        if new_name != ""
          try
            mod_name = new_name
            mod = Main.eval(Symbol(mod_name))
          catch e
            reset_module()
            is_except = true
          end
        else
          LineEdit.edit_insert(s, mod_name)
        end
        if is_except || !(typeof(mod) <: Module)
          LineEdit.clear_input_area(s)
          @warn "$(mod_name) is not a valid name of a module"
          #take!(buf)
          return false
        end
        #take!(buf)
      end
      return true
    end
    module_selector_mode.on_done = (s, buf, ok) -> begin
      global mod, mod_name
      in_module_eval_mode.prompt = mod_name * "> "
      buf = LineEdit.buffer(s)
      LineEdit.transition(s, in_module_eval_mode) do
        #LineEdit.state(s, in_module_eval_mode).input_buffer = buf
      end
    end
    in_module_eval_mode.on_done = (s, buf, ok) -> begin
      global mod, code
      code *= String(take!(buf))
      ast = Base.parse_input_line(code)
      # if code is not complete
      (!isa(ast,Expr) || ast.head != :incomplete) || return
      code = ""
      mod.eval(ast)
      LineEdit.transition(s, main_mode) do
        LineEdit.state(s, main_mode).input_buffer = buf
      end
    end
    in_module_eval_mode.on_enter = return_callback

    # inject into main mode
    keymap=Dict{Any, Any}(":" =>  (s, args...) -> begin
      if isempty(s) || position(LineEdit.buffer(s)) == 0
        buf = copy(LineEdit.buffer(s))
        LineEdit.transition(s, module_selector_mode) do
          LineEdit.state(s, module_selector_mode).input_buffer = buf
        end
      else
        LineEdit.edit_insert(s, ":")
      end
    end)
    main_mode.keymap_dict = LineEdit.keymap_merge(main_mode.keymap_dict, keymap)
  end
end

end # module

max_stars_repo_name: JuliaTagBot/EvalInModuleREPLMode

max_issues_repo_name: JuliaTagBot/EvalInModuleREPLMode

max_forks_repo_name: JuliaTagBot/EvalInModuleREPLMode


text:
include("ReactiveFlows.jl")
include("Connection.jl")
include("Channel.jl")
include("Exchange.jl")
include("Queue.jl")
include("Consumer.jl")
include("AmqpConfigs.jl")
include("Sinks.jl")
include("Integration/Integration.jl")


text:
abstract InitialStrategy
abstract MuSigmaStrategy <: InitialStrategy

###################
## short selling ##
###################

type MaxMuSS <: MuSigmaStrategy
    sigma::Float64

    function MaxMuSS(sigma::Float64)
        if sigma < 0.01
            error("Specified sigma must be larger than zero.")
        end
        return new(sigma)
    end
end

type MinSigmaSS <: MuSigmaStrategy
    mu::Float64

    MinSigmaSS(mu::Float64) = return new(mu)
end

type GMVSS <: MuSigmaStrategy

    GMVSS() = return new()
end

######################
## no short selling ##
######################

type MaxMu <: MuSigmaStrategy
    sigma::Float64

    function MaxMu(sigma::Float64)
        if sigma < 0.01
            error("Specified sigma must be larger than zero.")
        end
        return new(sigma)
    end
end

type MinSigma <: MuSigmaStrategy
    mu::Float64

    MinSigma(mu::Float64) = return new(mu)
end

type GMV <: MuSigmaStrategy

    GMV() = return new()
end

####################
## apply strategy ##
####################

function applyStrategy(strat::AssetMgmt.InitialStrategy,
                       estimator::Type{AssetMgmt.ExpWeighted},
                       data::Timematr)

    ## iterate over dates
    allDats = idx(data)
    nDats = length(allDats)

    ## preallocation
    nObs, nAss = size(data)
    allWgts = Array(Float64, nObs, nAss)
    pfMoments = Array(Float64, nObs, 2)
    modelEstimated = falses(nObs)

    for ii=1:nDats
        thisDate = allDats[ii]
        univ = AssetMgmt.estimate(estimator, data, thisDate)
        if AssetMgmt.isDef(univ)
            ## set estimation indicator to true
            modelEstimated[ii] = true

            wgts = AssetMgmt.optimizeWgts(strat, univ)
            allWgts[ii, :] = wgts

            ## calculate portfolio moments
            pfMu = AssetMgmt.getPMean(wgts[:], univ.Universe.mu)
            pfSigma = sqrt(AssetMgmt.getPVar(wgts[:], univ.Universe.sigma))
            pfMoments[ii, :] = [pfMu pfSigma]
        end
    end

    ## remove non-estimatable dates
    allWgts = allWgts[modelEstimated, :]
    pfMoments = pfMoments[modelEstimated, :]
    allDats = allDats[modelEstimated]

    ## DataFrame
    wgtsDf = composeDataFrame(allWgts, names(data))
    pfMomentsDf = Timematr(pfMoments, [:mu, :sigma], allDats)

    invs = Investments(wgtsDf, allDats)

    return invs, pfMomentsDf
end

##############
## optimize ##
##############

function optimizeWgts(s::MinSigma, univ::MuSigmaUniverse)
    muTarget = s.mu

    return getEffPfGivenMu(univ.Universe, muTarget)
end

function optimizeWgts(s::MaxMu, mod::MuSigmaUniverse)

end

function optimizeWgts(s::GMVSS, mod::MuSigmaUniverse)
    return getGMVSS(mod)
end


text:
# This example loads 4 short sound clips, each containing a whistle. It then forms the barycenter of those clips with varying barycentric coordinates and plot all barycenters in a grid.
using SpectralDistances, WAV, LPVSpectral
cd(@__DIR__)
y = map(1:4) do i
    filename = "whistle_$i.wav"
    sound, fs = wavread(filename)
    @show fs
    sound = vec(mean(sound, dims = 2)) .+ 0.005 .* randn.()
end

ml = minimum(length, y)
y  = [y[1:ml] for y in y] # Make sure they are all of equal length
fs = 44100
S  = melspectrogram.(y, 512, nmels = 64, fs = fs, fmin = 2500, fmax = 7000)
plot(plot.(S)..., colorbar = false)
EM = melspectrogram(mean(y), 512, nmels = 64, fs = fs, fmin = 2500, fmax = 7000)

## Plot the barycenter when all weights are equal (the Wasserstein mean)
λ = s1([1, 1, 1, 1])
B = barycenter_convolutional(
    S,
    λ,
    β             = 0.0005,
    tol           = 5e-6,
    iters         = 5000,
    ϵ             = 1e-100,
    dynamic_floor = -25,
    verbose       = true,
)
plot(
    plot(B, title = "Barycenter"),
    plot(EM, title = "Euclidean mean"),
    plot.(S, title = "")...,
    colorbar = false,
    layout   = (3, 2),
    xlabel   = false,
)

## Plot a 5×5 grid of barycenters with different barycentric coordinates.
N_fig = 5
plotopts = (
    colorbar  = false,
    titlefont = font(11),
    xlabel    = false,
    axis      = false,
    ylabel    = false,
)
plot(layout = (N_fig, N_fig))
v = I(4)
for i = 0:N_fig-1, j = 0:N_fig-1

    tx = i / (N_fig - 1)
    ty = j / (N_fig - 1)

    tmp1 = (1 - tx) * v[:, 1] + tx * v[:, 2]
    tmp2 = (1 - tx) * v[:, 3] + tx * v[:, 4]
    λ = Vector((1 - ty) * tmp1 + ty * tmp2)
    sp = i * N_fig + j + 1

    i == 0 && j == 0 && (plot!(S[1], sp=sp; plotopts...); continue)
    i == 0 && j == (N_fig - 1) && (plot!(S[3], sp=sp; plotopts...); continue)
    i == (N_fig - 1) && j == 0 && (plot!(S[2], sp=sp; plotopts...); continue)
    i == (N_fig - 1) && j == (N_fig - 1) && (plot!(S[4], sp=sp; plotopts...); continue)

    B = barycenter_convolutional(
        S,
        λ,
        β             = 0.0005,
        tol           = 1e-4,
        iters         = 5000,
        ϵ             = 1e-100,
        dynamic_floor = -25,
        verbose       = false,
    )
    plot!(
        B;
        sp        = sp,
        title     = @sprintf("%G  %G  %G  %G" , λ...),
        plotopts...
    )
end
current()


text:
using SeqBounds
using Test

@testset "SeqBounds.jl" begin
    io = IOBuffer();
    b = SeqBounds.bounds([0.2, 0.4, 0.6, 0.8, 1.0], 0.05; h = 0.05, side = :one, asf = :obf)
    @test b.zb[end] ≈ 1.7396609804214789 atol=1E-6
    @test_nowarn Base.show(io, b)
    b = SeqBounds.bounds([0.2, 0.4, 0.6, 0.8, 1.0], 0.05; h = 0.05, side = :two, asf = :pocock)
    @test b.zb[end] ≈ 2.385909219073807 atol=1E-6
    @test_nowarn Base.show(io, b)

    @test_nowarn SeqBounds.bounds([0.25, 0.5, 0.75, 1.0], 0.05; h = 0.04, side = :two, asf = :power)
    @test_nowarn SeqBounds.bounds([0.25, 0.5, 0.75, 1.0], 0.025; h = 0.04, side = :two, asf = :ep)
end


text:
function parsemetadatafromNMReDATA(file_strings::Vector{String})

    header_string = "> <NMREDATA_SOLVENT>"

    H_IDs = Vector{Int}(undef, 0)
    H_css = Vector{Float64}(undef, 0)

    record_flag = false

    for i = 1:length(file_strings)

        s = file_strings[i]

        if record_flag

            #tokens = split("_My input.string", (' ','_',',','.'))
            tokens = split(s, ',')
            #println("tokens = ", tokens)

            if length(tokens) >= 2
                tmp1 = tryparse(Int, tokens[1])
                tmp2 = tryparse(Float64, tokens[2])

                if typeof(tmp1) == Int && typeof(tmp2) == Float64
                    push!(H_IDs, tmp1)
                    push!(H_css, tmp2)
                else
                    record_flag = false
                end
            else
                record_flag = false
            end

        end

        if s == header_string
            record_flag = true
        end

    end

    return H_IDs, H_css
end

"""
sample `file_strings`:
> <NMREDATA_ASSIGNMENT>
12, 3.21706, 12 \
13, 3.21706, 13 \
14, 3.21706, 14 \
15, 3.21706, 15 \
16, 3.21706, 16 \
17, 3.21706, 17 \
18, 3.21706, 18 \
19, 3.21706, 19 \
20, 3.21706, 20 \
21, 2.40773, 21 \
22, 2.44334, 22 \
23, 3.42692, 23 \
24, 3.41518, 24 \
25, 4.55775, 25 \

"""
function parsecssfromNMReDATA(file_strings::Vector{String})

    header_string = "> <NMREDATA_ASSIGNMENT>"

    H_IDs = Vector{Int}(undef, 0)
    H_css = Vector{Float64}(undef, 0)

    record_flag = false

    for i = 1:length(file_strings)

        s = file_strings[i]

        if record_flag

            #tokens = split("_My input.string", (' ','_',',','.'))
            tokens = split(s, ',')
            #println("tokens = ", tokens)

            if length(tokens) >= 2
                tmp1 = tryparse(Int, tokens[1])
                tmp2 = tryparse(Float64, tokens[2])

                if typeof(tmp1) == Int && typeof(tmp2) == Float64
                    push!(H_IDs, tmp1)
                    push!(H_css, tmp2)
                else
                    record_flag = false
                end
            else
                record_flag = false
            end

        end

        if s == header_string
            record_flag = true
        end

    end

    return H_IDs, H_css
end

"""
Sample file_string:
> <NMREDATA_J>
12, 13, -12.400000 \
15, 17, -12.400000 \
18, 20, -12.400000 \
21, 22, -15.461709 \
21, 25, 6.477503 \
22, 25, 7.987374 \
23, 24, -14.339089 \
23, 25, 9.203557 \
24, 25, 2.284200 \

"""
function parseJsfromNMReDATA(file_strings::Vector{String})

    header_string = "> <NMREDATA_J>"

    J_IDs = Vector{Tuple{Int,Int}}(undef, 0)
    J_vals = Vector{Float64}(undef, 0)

    record_flag = false

    for i = 1:length(file_strings)

        s = file_strings[i]

        if record_flag

            tokens = split(s, (' ',','))
            # println("tokens = ", tokens)
            # tokens = SubString{String}["26", "", "27", "", "-12.000000", "\\"]

            if length(tokens) >= 5
                tmp1 = tryparse(Int, tokens[1])
                tmp2 = tryparse(Int, tokens[3])
                tmp3 = tryparse(Float64, tokens[5])

                # println("tmp1 = ", tmp1)
                # println("tmp2 = ", tmp2)
                # println("tmp3 = ", tmp3)

                if typeof(tmp1) == Int && typeof(tmp2) == Int &&
                        typeof(tmp3) == Float64

                    push!(J_IDs, (tmp1,tmp2))
                    push!(J_vals, tmp3)
                else
                    record_flag = false
                end
            else
                record_flag = false
            end
        end

        if s == header_string
            record_flag = true
        end

    end

    return J_IDs, J_vals
end

function partitionJcouplings(  J_IDs::Vector{Tuple{Int,Int}},
                                J_vals::Vector{T}) where T <: Real

    #
    @assert length(J_IDs) == length(J_vals)

    H_IDs_sys = Vector{Vector{Int}}(undef, 0)
    J_IDs_sys = Vector{Vector{Tuple{Int,Int}}}(undef, 0)
    J_vals_sys = Vector{Vector{T}}(undef, 0)

    for i = 1:length(J_IDs)
        a, b = J_IDs[i]

        # fetch fresh H_IDs_sys.
        H_IDs_sys = collect(finduniqueIDs(J_IDs_sys[m]) for m = 1:length(J_IDs_sys))

        #println("H_IDs_sys = ", H_IDs_sys)

        presence_flag = falses(length(H_IDs_sys))

        # search through existing cliques
        for m = 1:length(H_IDs_sys)

            # search within the current clique.
            for l = 1:length(H_IDs_sys[m])
                presence_flag[m] = presence_flag[m] | (H_IDs_sys[m][l] == a) | (H_IDs_sys[m][l] == b)
            end
        end

        # update
        if any(presence_flag)

            js = findall(presence_flag)

            # add to the first existing subsystem.
            push!(J_IDs_sys[js[1]], J_IDs[i])
            push!(J_vals_sys[js[1]], J_vals[i])

            if length(js) > 1
                # merge all existing subsystems that share the hydrogens in this ID.
                consolidatearray!(J_IDs_sys, js)
                consolidatearray!(J_vals_sys, js)
            end

        else
            # start new subsystem to the end of J_IDs_sys.
            push!(J_IDs_sys, Vector{Tuple{Int,Int}}(undef,1))
            J_IDs_sys[end][1] = J_IDs[i]

            push!(J_vals_sys, Vector{T}(undef,1))
            J_vals_sys[end][1] = J_vals[i]
        end

        ## force update on H_IDs_sys. Need this for for 2-spin systems.
        # fetch fresh H_IDs_sys.
        H_IDs_sys = collect(finduniqueIDs(J_IDs_sys[m]) for m = 1:length(J_IDs_sys))

    end

    return J_IDs_sys, J_vals_sys, H_IDs_sys
end

function finduniqueIDs(J_IDs::Vector{Tuple{Int,Int}})

    out = Vector{Int}(undef, 0)
    for i = 1:length(J_IDs)

        push!(out, J_IDs[i][1])
        push!(out, J_IDs[i][2])
    end

    return unique(out)
end

function consolidatearray!(X::Vector{Vector{T}}, inds::Vector{Int})::Nothing where T
    @assert length(inds) > 1
    j = inds[1]
    @assert 1 <= j <= length(X)

    for i = 2:length(inds)
        @assert 1 <= inds[i] <= length(X)

        push!(X[j], X[i]...)
    end

    deleteat!(X, inds[2:end])

    return nothing
end

function getcssys(  H_IDs_sys::Vector{Vector{Int}},
                    H_IDs::Vector{Int},
                    H_css::Vector{T}) where T <: Real

    @assert length(H_IDs) == length(H_css)

    N_subsystems = length(H_IDs_sys)

    # for sanity-checking that H_IDs_sys have unique finest-grain elements.
    processed_flags = falses(length(H_IDs))

    # output.
    css_sys = Vector{Vector{T}}(undef, N_subsystems)

    for m = 1:length(H_IDs_sys)

        L = length(H_IDs_sys[m])

        css_sys[m] = Vector{T}(undef, L)

        for l = 1:L

            t = H_IDs_sys[m][l]

            k = findfirst(xx->xx==t, H_IDs)
            @assert typeof(k) != Nothing
            @assert processed_flags[k] == false

            # store.
            css_sys[m][l] = H_css[k]

            # book keep.
            processed_flags[k] = true
        end
    end

    return css_sys
end

function getJsys(  J_IDs_sys::Vector{Vector{Tuple{Int,Int}}},
                    J_vals_sys::Vector{Vector{T}},
                    H_IDs_sys::Vector{Vector{Int}}) where T <: Real

    N_subsystems = length(H_IDs_sys)
    @assert length(J_IDs_sys) == length(J_vals_sys) == N_subsystems

    # for sanity-checking that H_IDs_sys have unique finest-grain elements.
    #processed_flags = falses(length(H_IDs))

    # output.
    𝐽_IDs_sys = Vector{Vector{Tuple{Int,Int}}}(undef, N_subsystems)

    for m = 1:length(J_IDs_sys)

        # parse & set up.
        Hs = H_IDs_sys[m]
        Js = J_IDs_sys[m]

        N = length(Js)

        # allocate.
        𝐽_IDs_sys[m] = Vector{Tuple{Int,Int}}(undef, N)

        for i = 1:N

            a, b = Js[i]

            k = findfirst(xx->xx==a, Hs)
            @assert typeof(k) != Nothing

            z = findfirst(xx->xx==b, Hs)
            @assert typeof(z) != Nothing

            # store.
            𝐽_IDs_sys[m][i] = (k,z)
        end
    end

    return 𝐽_IDs_sys
end

function createsingletsysems(   H_IDs,
                                H_IDs_multiplets_sys,
                                H_css::Vector{T};
                                zero_tol = 1e-6) where T
    #
    M = length(H_IDs_multiplets_sys)

    H_set = Set(H_IDs)

    for m = 1:M
        A = Set(H_IDs_multiplets_sys[m])

        H_set = setdiff(H_set, A)
    end

    # remainder goes into a new set each, depending on their chemical shift.
    R = collect(H_set)
    R_cs = Vector{T}(undef, length(R))

    for i = 1:length(R)

        k = findfirst(xx->xx==R[i], H_IDs)
        @assert typeof(k) != Nothing

        R_cs[i] = H_css[k]
    end

    # consolidate groups with similar cs (values within zero_tol).
    cs_singlets = Vector{Vector{T}}(undef, 0)
    H_singlets = Vector{Vector{Int}}(undef, 0)

    while length(R_cs) > 0
        t = R_cs[1]

        inds = findall(xx->isnumericallyclose(xx, t, zero_tol), R_cs)

        push!(cs_singlets, R_cs[inds])
        push!(H_singlets, R[inds])

        deleteat!(R_cs, inds)
    end

    # compact representation.
    cs_singlets_compact = collect( cs_singlets[m][1] for m = 1:length(cs_singlets) )

    return H_singlets, cs_singlets, cs_singlets_compact
end

function constructLUTcss(   css_sys::Vector{Vector{T}};
                            zero_tol = 1e-6) where T <: Real
    #
    N_subsystems = length(css_sys)

    cs_LUT = Vector{Vector{Vector{Int}}}(undef, N_subsystems)
    p_cs = Vector{Vector{T}}(undef, N_subsystems)

    for m = 1:N_subsystems

        # set up.
        cs = css_sys[m]
        N = length(css_sys[m])
        available_flags = trues(N)

        # allocate.
        cs_LUT[m] = Vector{Vector{Int}}(undef,0)
        p_cs[m] = Vector{T}(undef,0)

        for i = 1:N
            if available_flags[i]

                # search.
                t = cs[i]

                inds = findall(xx->isnumericallyclose(xx, t, zero_tol), cs)

                # store.
                push!(cs_LUT[m], inds)
                push!(p_cs[m], t)

                # book keep.
                for l in inds
                    available_flags[l] = false
                end
            end
        end
    end

    return cs_LUT, p_cs
end

### remove spin groups that have only one chem shift, but non-zero J-coupling.
# Those are really singlets.
function removeisolatedcs!(css_sys::Vector{Vector{T}},
                            cs_singlets::Vector{Vector{T}},
                            cs_singlets_compact::Vector{T},
                            H_singlets,
                            H_IDs_sys::Vector{Vector{Int}},
                            J_IDs_sys::Vector{Vector{Tuple{Int,Int}}},
                            J_vals_sys::Vector{Vector{T}},
                            𝐽_IDs_sys::Vector{Vector{Tuple{Int,Int}}};
                            zero_tol_sigdigits::Int = 6,
                            zero_tol = 1e-10) where T

    # add approximate spin groups as singlet groups.
    keep_flags = trues(length(css_sys))
    for i = 1:length(css_sys)
        #
        tmp = unique(x -> round(x, sigdigits = zero_tol_sigdigits), css_sys[i])
        if length(tmp) == 1
            keep_flags[i] = false

            new_cs_group = tmp .* ones(T, length(css_sys[i]))
            push!(cs_singlets, new_cs_group)

            push!(cs_singlets_compact, tmp[1])

            push!(H_singlets, H_IDs_sys[i])
        end
    end

    # remove those sping groups from spin system-related quantities.
    delete_flags = collect( !keep_flags[i] for i = 1:length(keep_flags) )

    deleteat!(H_IDs_sys, delete_flags)
    deleteat!(css_sys, delete_flags)

    deleteat!(J_IDs_sys, delete_flags)
    deleteat!(J_vals_sys, delete_flags)
    deleteat!(𝐽_IDs_sys, delete_flags)

    # merge singlet groups if neccessary.
    unique_css = unique(x -> round(x, sigdigits = zero_tol_sigdigits), cs_singlets_compact)
    if length(unique_css) != length(cs_singlets_compact)
        # we can merge at least two singlet groups.

        # take care of the cs_singlets.
        for i = 1:length(unique_css)

            x = unique_css[i]

            merge_flags = collect( isapprox(cs_singlets_compact[i], x; atol = zero_tol) for i = 1:length(cs_singlets_compact))
            merge_inds = collect(1:length(cs_singlets_compact))[merge_flags]
            @assert length(merge_inds) > 0

            # add to the keep_ind.
            keep_ind = merge_inds[1]
            for j = 2:length(merge_inds)

                k = merge_inds[j]
                push!(cs_singlets[keep_ind], cs_singlets[k]...)
                push!(H_singlets[keep_ind], H_singlets[k]...)
            end

            if length(merge_inds) > 1
                # delete the merge_inds that isn't the keep_ind (which is the first entry).
                delete_flags = [false; merge_flags[2:end]]
                deleteat!(cs_singlets, delete_flags)
                deleteat!(H_singlets, delete_flags)
            end
        end

        # update compact version.
        resize!(cs_singlets_compact, length(cs_singlets))
        for i = 1:length(cs_singlets)
            cs_singlets_compact[i] = cs_singlets[i][1]
        end
    end

    return nothing
end

function mergefirst(x::Vector{T}, a::T; tol::T)::Int where T
    for i = 1:length(x)
        if isapprox(x[i], a, atol = tol)
            return i
        end
    end

    return 0
end

#### perturb.

function additiveperturbation(x::T, δ::T)::T where T
    return x + δ
end

# function multiplicativeperturbation(x::T, δ::T)::T where T
#     return x*δ
# end

function getJperturbed(  J_vals_sys::Vector{Vector{T}},
                        perturbfunc::Function)::Vector{Vector{T}} where T <: Real

    #
    N_subsystems = length(J_vals_sys)

    J_p_sys = Vector{Vector{T}}(undef, N_subsystems)

    for m = 1:length(J_vals_sys)
        N = length(J_vals_sys[m])

        J_p_sys[m] = Vector{T}(undef, N)

        for i = 1:N
            J_p_sys[m][i] = perturbfunc(J_vals_sys[m][i])
        end
    end

    return J_p_sys
end


text:
module Infinity

using Dates: Period, TimeType, UTInstant
using Requires

export Infinite, PosInf, NegInf, ∞, InfMinusInfError, InfExtendedReal, InfExtendedTime

function __init__()
    @require TimeZones="f269a46b-ccf7-5d73-abea-4c690281aa53" include("infextendedtime/timezones.jl")
end

# Utils
include("utils.jl")

# Infinite
include("infinite/base.jl")
include("infinite/arithmetic.jl")
include("infinite/io.jl")
include("infinite/comparison.jl")
include("infinite/conversion.jl")
include("infinite/parse.jl")
include("infinite/rand.jl")

# InfExtendedReal
include("infextendedreal/base.jl")
include("infextendedreal/arithmetic.jl")
include("infextendedreal/comparison.jl")
include("infextendedreal/conversion.jl")
include("infextendedreal/parse.jl")

# InfExtendedTime
include("infextendedtime/base.jl")
include("infextendedtime/arithmetic.jl")
include("infextendedtime/comparison.jl")
include("infextendedtime/parse.jl")

# Extended Common Functions
include("common.jl")
end


text:
if get(ENV, "BUILDKITE", "false") == "true"
    # This file requires a GPU in order to run. It gets tested as part of the
    # JuliaGPU CI on Buildkite. Contact @odow for more details.
    include("test_gpu.jl")
    exit(0)
end

using Test
using SCS

include("test_problems.jl")
for s in SCS.available_solvers
    feasible_basic_problems(s)
end

include("MOI_wrapper.jl")


text:
using WAVEFORM, LinearAlgebra, Test

###################################################################################################
# wave_base.jl

# 2D model
n = 101 .* [1;1]
d = 10.0 .*[1;1]
o = 0.0 .* [1;1]

freqs = [5.0;10.0;15.0]
t0 = 0.0
f0 = 10.0
unit = "m/s"

vel_background = 2000
L = n.*d

xsrc = 0.0:100.0:L[2]
ysrc = [0.0]
zsrc = [10.0]

# Receiver grid definition
xrec = 0:10.0:L[2]
yrec = [0.0]
zrec = [950.0]

# Model type containing the domain geometry
model = Model{Int64,Float64}(n,d,o,t0,f0,unit,freqs,xsrc,ysrc,zsrc,xrec,yrec,zrec)

@test typeof(model) == Model{Int64, Float64}
@test model.n == n
@test model.d == d
@test model.o == o

# 2D: helm2d_chen9p or helm2d_std7; 3D: helm3d_operto27 or helm3d_std9
pde_scheme = WAVEFORM.helm2d_chen9p
cut_pml = true
implicit_matrix = true
npml = [1 1; 1 1]
misfit = least_squares;
srcfreqmask = trues(length(xsrc), length(freqs))
lsopts = LinSolveOpts(; tol=1e-9, maxit=1000, solver=:lufact, precond=:identity)

# Misfit function for the objective
pdeopts = PDEopts(pde_scheme, n, d, o, cut_pml, implicit_matrix, npml, minimum, srcfreqmask, lsopts)

@test typeof(pdeopts) == PDEopts{Int64, Float64}
@test pdeopts.comp_n == n
@test pdeopts.comp_d == d
@test pdeopts.comp_o == o
@test pdeopts.srcfreqmask == srcfreqmask

###################################################################################################
# wave_util.jl

idx = index_block([1,2,3,4], 2)
@test size(idx) == (2,)
@test idx[1] == [1,2]
@test idx[2] == [3,4]

w = fwi_wavelet(freqs, t0, f0)
@test typeof(w) == Vector{ComplexF64}
@test length(w) == length(freqs)

g1, g2 = odn_to_grid(o, d, n)
@test length(g1) == n[1]
@test length(g2) == n[2]
@test g1[1] == o[1]
@test g2[1] == o[2]
@test g1[end] == o[1] + (n[1]-1)*d[1]
@test g2[end] == o[2] + (n[2]-1)*d[2]

o_, d_, n_ = grid_to_odn([g1, g2])
@test o_ == o
@test d_ == d
@test n_ == n

###################################################################################################
# helm.jl

ndims=2
n = 101 .* [1;1]
npml = npml = [1 1; 1 1]
Pext, Ppad = WAVEFORM.get_pad_ext_ops(n,npml,ndims)

x = randn((n...))
y = randn(((n + sum(npml, dims=2))...))

@test dot(vec(y), Pext*vec(x)) - dot(vec(x), Pext'*vec(y)) < 1e-9
@test dot(vec(y), Ppad*vec(x)) - dot(vec(x), Ppad'*vec(y)) < 1e-9

phys_to_comp = Pext
comp_to_phys = Ppad'

# Param to wavenum
f, df, ddf = param_to_wavenum(vel_background,freqs[1],"m/s")
f, df, ddf = param_to_wavenum(vel_background,freqs[1],"s/m")
f, df, ddf = param_to_wavenum(vel_background,freqs[1],"s2/km2")


text:
# TODO move to ...

# """
#     $(TYPEDEF)
# Abstract parent struct for big data entry.
# """
# abstract type AbstractBigDataEntry end

# --- AbstractBigData Interfaces ---
# fields to implement:
# - key::Symbol
# available methods:
# - addBigDataEntry!
# - getBigDataEntry
# - updateBigDataEntry!
# - deleteBigDataEntry!
# - getBigDataEntries
# - getBigDataKeys

export  addBigDataEntry!,
        getBigDataEntry,
        updateBigDataEntry!,
        deleteBigDataEntry!,
        getBigDataEntries,
        getBigDataKeys,
        MongodbBigDataEntry,
        FileBigDataEntry

# Methods

#TODO should this return Bool or the modified Variable?
"""
    $(SIGNATURES)
Add Big Data Entry to a DFG variable
"""
function addBigDataEntry!(var::AbstractDFGVariable, bde::AbstractBigDataEntry)::Bool
    haskey(var.bigData,bde.key) && @warn "$(bde.key) already exists in variable, overwriting!"
    var.bigData[bde.key] = bde
    return true
end

"""
    $(SIGNATURES)
Add Big Data Entry to distrubuted factor graph.
Should be extended if DFG variable is not returned by by reference.
"""
function addBigDataEntry!(dfg::AbstractDFG, label::Symbol, bde::AbstractBigDataEntry)::Bool
    return addBigDataEntry!(getVariable(dfg, label), bde)
end

"""
    $(SIGNATURES)
Get big data entry
"""
function getBigDataEntry(var::AbstractDFGVariable, key::Symbol)::AbstractBigDataEntry
    return var.bigData[key]
end
function getBigDataEntry(dfg::AbstractDFG, label::Symbol, key::Symbol)::AbstractBigDataEntry
    return getBigDataEntry(getVariable(dfg, label), key)
end

"""
    $(SIGNATURES)
Update big data entry
"""
function updateBigDataEntry!(var::AbstractDFGVariable,  bde::AbstractBigDataEntry)::Bool#TODO should this return Bool?
    !haskey(var.bigData,bde.key) && (@error "$(bde.key) does not exist in variable!"; return false)
    var.bigData[bde.key] = bde
    return true
end
function updateBigDataEntry!(dfg::AbstractDFG, label::Symbol,  bde::AbstractBigDataEntry)::Bool
    updateBigDataEntry!(getVariable(dfg, label), bde)
end

"""
    $(SIGNATURES)
Delete big data entry
"""
function deleteBigDataEntry!(var::AbstractDFGVariable, key::Symbol)::AbstractBigDataEntry #users responsibility to delete big data in db before deleting entry
    bde = getBigDataEntry(var, key)
    delete!(var.bigData, key)
    return bde
end

function deleteBigDataEntry!(dfg::AbstractDFG, label::Symbol, key::Symbol)::AbstractBigDataEntry #users responsibility to delete big data in db before deleting entry
    deleteBigDataEntry!(getVariable(dfg, label), key)
end

"""
    $(SIGNATURES)
Get big data entries, Vector{AbstractBigDataEntry}
"""
function getBigDataEntries(var::AbstractDFGVariable)::Vector{AbstractBigDataEntry}
    #or should we return the iterator, Base.ValueIterator{Dict{Symbol,AbstractBigDataEntry}}?
    collect(values(var.bigData))
end
function getBigDataEntries(dfg::AbstractDFG, label::Symbol)::Vector{AbstractBigDataEntry}
    #or should we return the iterator, Base.ValueIterator{Dict{Symbol,AbstractBigDataEntry}}?
    getBigDataEntries(getVariable(dfg, label))
end

"""
    $(SIGNATURES)
getBigDataKeys
"""
function getBigDataKeys(var::AbstractDFGVariable)::Vector{Symbol}
    collect(keys(var.bigData))
end
function getBigDataKeys(dfg::AbstractDFG, label::Symbol)::Vector{Symbol}
    getBigDataKeys(getVariable(dfg, label))
end

# Types <: AbstractBigDataEntry
"""
    $(TYPEDEF)
BigDataEntry in MongoDB.
"""
struct MongodbBigDataEntry <: AbstractBigDataEntry
    key::Symbol
    oid::NTuple{12, UInt8} #mongodb object id
    #maybe other fields such as:
    #flags::Bool ready, valid, locked, permissions
    #MIMEType::Symbol
end

"""
    $(TYPEDEF)
BigDataEntry in a file.
"""
struct FileBigDataEntry <: AbstractBigDataEntry
    key::Symbol
    filename::String
end


text:
using Gnuplot
# archimedean spiral
a, m, z₀ = 1, 2.1, 0
φ = LinRange(0,20π,500)
r = a*φ
x, y, z = r .* cos.(φ), r .* sin.(φ), m .* r .+ z₀
function theme(bgcolor = "#212946"; borderc ="white",
        ticsc = "white", ylabc = "white", gridst = 4,
        xlabc = "white", gridc = "#2A3459", labc = "white")
    bgcp1 = "set object rectangle from screen 0,0 to screen 1,1"
    bgcp2 = " behind fc '$(bgcolor)' fs solid noborder"
    bgcolor = bgcp1*bgcp2
    @gp :- "set border lw 1 lc '$(borderc)'"
    @gp :- "set tics textcolor rgb '$(ticsc)'"
    @gp :- bgcolor
    @gp :- "set ylabel textcolor '$(ylabc)'"
    @gp :- "set xlabel textcolor '$(xlabc)'"
    @gp :- "set grid ls 1 lc '$(gridc)' dt $(gridst)"
    @gp :- "set key t r textcolor '$(labc)'"
end

@gsp "set xyplane 0" "set view equal xyz" "set auto fix" :-
theme("black")
@gsp :- xlab = "x" ylab = "y"
@gsp :- xr=extrema(x) yr=extrema(y) zr=extrema(z)
@gsp :- "i=2"
# line and point
@gsp :- x y z "every ::1::i w l notit lc palette" palette(:Wistia)
@gsp :- x y z "every ::i::i w points notit lc 'red'"
@gsp :- x y 0*z z "every ::1::i w l notit lc palette lt 2"
# animation
for frame in 2:5:length(x)
  @gsp :- frame "i=$frame" "replot" :-
end
@gsp # show animation
save(term="gif animate size 900,600 delay 1", output="archimedean.gif") # hide

max_stars_repo_name: lazarusA/gnuplot-examples

max_issues_repo_name: lazarusA/gnuplot-examples

max_forks_repo_name: lazarusA/gnuplot-examples


text:
using Test
using Pkg

@testset "inference" begin
    f() = Pkg.Types.STDLIBS_BY_VERSION
    @inferred f()
    f() = Pkg.Types.UNREGISTERED_STDLIBS
    @inferred f()
end


text:
"""
Levels in a hierarchy must have the following interface:
    1. restrict(level, x, b)
    2. prehook(level, x, b)
    3. posthook(level, x, b)
    4. prolongate(level, x, b)

TODO: I'm not sure about this interface.
"""
module Hierarchy

using SparseRelaxation

export prolongator_from_aggregates, AMGLevelm, DirectSolve, create_amg_level,
       create_amg_hierarchy, vcycle

"""
    prolongator_from_aggregates(Agg :: Vector)

Creates a prolongation operator `P` from `Agg`.
"""
prolongator_from_aggregates(Agg :: Vector) = sparse(1:length(Agg), Agg, ones(Agg))

"""
    immutable AMGLevel
        A :: SparseMatrixCSC # Matrix
        R :: SparseMatrixCSC # Restriction
        P :: SparseMatrixCSC # Prolongation
    end
"""
immutable AMGLevel
    A :: SparseMatrixCSC
    R :: SparseMatrixCSC
    P :: SparseMatrixCSC
end

immutable DirectSolve
    A :: SparseMatrixCSC
end

function create_amg_level(A :: SparseMatrixCSC, aggregation, strength)
    P = prolongator_from_aggregates(aggregation(strength(A)))
    R = transpose(P)
    AMGLevel(A, R, P)
end

# TODO: use coarse nnz or size?
function create_amg_hierarchy(A :: SparseMatrixCSC, aggregation, strength, coarse_size)
    if size(A, 1) <= coarse_size
        [DirectSolve(A)]
    else
        lvl = create_amg_level(A, aggregation, strength)
        [lvl; create_amg_hierarchy(lvl.R*A*lvl.P, aggregation, strength, coarse_size)]
    end
end

vcycle(lvl :: DirectSolve, x, b, levels) = lvl.A \ b

function vcycle(lvl :: AMGLevel, x, b, levels)
    gauss_seidel!(lvl.A, x, b)
    #= xr = lvl.R * x =#
    br = lvl.R * b
    x += lvl.P * vcycle(levels[1], zeros(br), br, levels[2:end])
    gauss_seidel!(lvl.A, x, b)
    x
end

vcycle(levels, x, b) = vcycle(levels[1], x, b, levels[2:end])

end


text:
#
# Each time this file is executed, two lines will be appended to
# 'results/figure4.csv'. Run 50 times to generate a boxplot similar
# to the one in
#
#   D. Neumann, T. Wiese, and W. Utschick, Learning the MMSE Channel Estimator,
#   IEEE Transactions on Signal Processing, 2018.
#
# (Closing Julia in between runs will ensure that the TensorFlow graph is
# reset and that memory is freed up after each run.)
#

push!(LOAD_PATH,".")
using DataFrames
using CSV
import SCM3GPP; const scm = SCM3GPP
import CondNormalMMSE; const mmse = CondNormalMMSE
import CondNormalTF; const cntf = CondNormalTF

include("sim_helpers.jl")
include("more_estimators.jl") # OMP and Genie MMSE

verbose = true
#-------------------------------------
# Simulation parameters
#
write_file = true
filename   = "results/figure4.csv"
nBatches   = 100
nBatchSize = 100

#-------------------------------------
# Channel Model
#
snr        = 0 # [dB]
AS         = 2.0 # standard deviation of Laplacian (angular spread)
nCoherence = 1
Channel    = scm.SCMMulti(pathAS=AS, nPaths=3)
# method that generates "nBatch" channel realizations
get_channel(nAntennas, nCoherence, nBatches) = scm.generate_channel(Channel, nAntennas, nCoherence=nCoherence, nBatches = nBatches)
# method that samples C_delta from delta prior
get_cov(nAntennas) = scm.toeplitzHe( scm.generate_channel(Channel, nAntennas, nCoherence=1)[2][:] )
# get circulant vector that generates all covariance matrices for arbitrary delta (here: use delta=0)
get_circ_cov_generator(nAntennas) = real(scm.best_circulant_approximation(scm.scm_channel([0.0],[1.0],nAntennas,AS=AS)[2]))

#-------------------------------------
# Learning Algorithm parameters
#
nLayers = 2
nLearningBatches   = 6000
nLearningBatchSize = 20

init_params = Vector{Any}(2)

init_params[1] = Dict{Symbol,Any}()
init_params[1][:nAntennas]   = [   8;  16;  32;  64]
init_params[1][:nBatches]    = [1000;1000;1000]
init_params[1][:nBatchSize]  = [  20;  20;  20]
init_params[1][:snrs]        = [ snr; snr; snr]
init_params[1][:get_channel] = (nAntennas,nBatches) -> get_channel(nAntennas, nCoherence, nBatches)
init_params[1][:learning_rates] = Dict{Symbol,Vector{Float64}}()
init_params[1][:learning_rates][:CircReLUHier] = 1e-4*64./init_params[1][:nAntennas]

init_params[2] = Dict{Symbol,Any}()
init_params[2][:nAntennas]   = [   8;  16;  32;  64; 128]
init_params[2][:nBatches]    = [1000;1000;1000;2000]
init_params[2][:nBatchSize]  = [  20;  20;  20;  20]
init_params[2][:snrs]        = [ snr; snr; snr; snr]
init_params[2][:get_channel] = (nAntennas,nBatches) -> get_channel(nAntennas, nCoherence, nBatches)
init_params[2][:learning_rates] = Dict{Symbol,Vector{Float64}}()
init_params[2][:learning_rates][:CircReLUHier] = 1e-4*64./init_params[2][:nAntennas]

df = DataFrame()
# read results from previous run
if isfile(filename)
    df = CSV.read(filename)
end

srand(size(df,1)) # use number of entries in results as seed for random number generator

results = DataFrame()
for i in 1:length(init_params)
    nAntennas = init_params[i][:nAntennas][end]

    # Network estimators
    nn_est = Dict{Symbol,Any}()
    nn_est[:CircReLU] = cntf.ConvNN(nLayers, init_params[i][:nAntennas][end],
                                    transform = circ_trans,
                                    learning_rate = init_params[i][:learning_rates][:CircReLUHier][end])
    nn_est_hier = Dict{Symbol,Any}()
    nn_est_hier[:CircReLUHier] = cntf.ConvNN(nLayers, init_params[i][:nAntennas][1],
                                             transform = circ_trans,
                                             learning_rate = init_params[i][:learning_rates][:CircReLUHier][1])

    # Hierarchical training:
    init_hier!(nn_est_hier, init_params[i], verbose = verbose)
    train!(nn_est_hier, snr = snr, nBatches = nLearningBatches, get_channel = () -> get_channel(nAntennas, nCoherence, nLearningBatchSize), verbose = verbose)

    train!(nn_est, snr = snr, nBatches = nLearningBatches + sum(init_params[i][:nBatches]), get_channel = () -> get_channel(nAntennas, nCoherence, nLearningBatchSize), verbose = verbose)

    algs = Dict{Symbol,Any}()
    for (alg,nn) in nn_est
        algs[alg] = (y,h,h_cov) -> cntf.estimate(nn, y)
    end
    for (alg,nn) in nn_est_hier
        algs[alg] = (y,h,h_cov) -> cntf.estimate(nn, y)
    end

    (errs,rates) = evaluate(algs, snr = snr, nBatches = nBatches, get_channel = () -> get_channel(nAntennas, nCoherence, nBatchSize), verbose = verbose)

    for alg in keys(algs)
        new_row = DataFrame(MSE        = errs[alg],
                            rate       = rates[alg],
                            Algorithm  = String(alg),
                            SNR        = snr,
                            nAntennas  = nAntennas,
                            nCoherence = nCoherence)

        if isempty(results)
            results = new_row
        else
            results = vcat(results,new_row)
        end
    end
end
@show results
if write_file
    CSV.write(filename, results, append=true)
end

max_stars_repo_name: tum-msv/learning-mmse-est


text:
immutable Complex{T<:Real} <: Number
    re::T
    im::T
end
Complex(x::Real, y::Real) = Complex(promote(x,y)...)
Complex(x::Real) = Complex(x, zero(x))

const im = Complex(false,true)

typealias Complex128 Complex{Float64}
typealias Complex64  Complex{Float32}
typealias Complex32  Complex{Float16}

sizeof{T<:Real}(::Type{Complex{T}}) = 2*sizeof(T)

convert{T<:Real}(::Type{Complex{T}}, x::Real) = Complex{T}(x,0)
convert{T<:Real}(::Type{Complex{T}}, z::Complex) = Complex{T}(real(z),imag(z))
convert{T<:Real}(::Type{T}, z::Complex) =
    isreal(z) ? convert(T,real(z)) : throw(InexactError())

convert(::Type{Complex}, z::Complex) = z
convert(::Type{Complex}, x::Real) = Complex(x)

promote_rule{T<:Real,S<:Real}(::Type{Complex{T}}, ::Type{S}) =
    Complex{promote_type(T,S)}
promote_rule{T<:Real,S<:Real}(::Type{Complex{T}}, ::Type{Complex{S}}) =
    Complex{promote_type(T,S)}

widen{T}(::Type{Complex{T}}) = Complex{widen(T)}

real(z::Complex) = z.re
imag(z::Complex) = z.im
real(x::Real) = x
imag(x::Real) = zero(x)
reim(z) = (real(z), imag(z))

isreal(x::Real) = true
isreal(z::Complex) = imag(z) == 0
isimag(z::Number) = real(z) == 0
isinteger(z::Complex) = isreal(z) & isinteger(real(z))
isfinite(z::Complex) = isfinite(real(z)) & isfinite(imag(z))
isnan(z::Complex) = isnan(real(z)) | isnan(imag(z))
isinf(z::Complex) = isinf(real(z)) | isinf(imag(z))

complex(x::Real, y::Real) = Complex(x, y)
complex(x::Real) = Complex(x)
complex(z::Complex) = z

complex128(r::Float64, i::Float64) = Complex{Float64}(r, i)
complex128(r::Real, i::Real) = complex128(float64(r),float64(i))
complex128(z) = complex128(real(z), imag(z))
complex64(r::Float32, i::Float32) = Complex{Float32}(r, i)
complex64(r::Real, i::Real) = complex64(float32(r),float32(i))
complex64(z) = complex64(real(z), imag(z))
complex32(r::Float16, i::Float16) = Complex{Float16}(r, i)
complex32(r::Real, i::Real) = complex32(float16(r),float16(i))
complex32(z) = complex32(real(z), imag(z))

for fn in _numeric_conversion_func_names
    @eval $fn(z::Complex) = Complex($fn(real(z)),$fn(imag(z)))
end

function complex_show(io::IO, z::Complex, compact::Bool)
    r, i = reim(z)
    compact ? showcompact(io,r) : show(io,r)
    if signbit(i)==1 && !isnan(i)
        i = -i
        print(io, compact ? "-" : " - ")
    else
        print(io, compact ? "+" : " + ")
    end
    compact ? showcompact(io, i) : show(io, i)
    if !(isa(i,Integer) && !isa(i,Bool) || isa(i,FloatingPoint) && isfinite(i))
        print(io, "*")
    end
    print(io, "im")
end
complex_show(io::IO, z::Complex{Bool}, compact::Bool) =
    print(io, z == im ? "im" : "Complex($(z.re),$(z.im))")
show(io::IO, z::Complex) = complex_show(io, z, false)
showcompact(io::IO, z::Complex) = complex_show(io, z, true)

function read{T<:Real}(s::IO, ::Type{Complex{T}})
    r = read(s,T)
    i = read(s,T)
    Complex{T}(r,i)
end
function write(s::IO, z::Complex)
    write(s,real(z))
    write(s,imag(z))
end

## generic functions of complex numbers ##

==(z::Complex, w::Complex) = (real(z) == real(w)) & (imag(z) == imag(w))
==(z::Complex, x::Real) = isreal(z) && real(z) == x
==(x::Real, z::Complex) = isreal(z) && real(z) == x

isequal(z::Complex, w::Complex) = isequal(real(z),real(w)) & isequal(imag(z),imag(w))

hash(z::Complex) = bitmix(hash(real(z)),hash(imag(z)))

conj(z::Complex) = Complex(real(z),-imag(z))
abs(z::Complex)  = hypot(real(z), imag(z))
abs2(z::Complex) = real(z)*real(z) + imag(z)*imag(z)
inv(z::Complex)  = conj(z)/abs2(z)
inv{T<:Integer}(z::Complex{T}) = inv(float(z))
sign(z::Complex) = z/abs(z)

-(z::Complex) = Complex(-real(z), -imag(z))
+(z::Complex, w::Complex) = Complex(real(z) + real(w), imag(z) + imag(w))
-(z::Complex, w::Complex) = Complex(real(z) - real(w), imag(z) - imag(w))
*(z::Complex, w::Complex) = Complex(real(z) * real(w) - imag(z) * imag(w),
                                    real(z) * imag(w) + imag(z) * real(w))

# adding or multiplying real & complex is common
*(x::Bool, z::Complex) = ifelse(x, z, zero(z))
*(z::Complex, x::Bool) = ifelse(x, z, zero(z))
*(x::Real, z::Complex) = Complex(x * real(z), x * imag(z))
*(z::Complex, x::Real) = Complex(x * real(z), x * imag(z))
+(x::Real, z::Complex) = Complex(x + real(z), imag(z))
+(z::Complex, x::Real) = Complex(x + real(z), imag(z))
-(x::Real, z::Complex) = Complex(x - real(z), -imag(z))
-(z::Complex, x::Real) = Complex(real(z) - x, imag(z))

/(z::Number, w::Complex) = z*inv(w)
/(a::Real  , w::Complex) = a*inv(w)
/(z::Complex, x::Real) = Complex(real(z)/x, imag(z)/x)

function /(a::Complex, b::Complex)
    are = real(a); aim = imag(a); bre = real(b); bim = imag(b)
    if abs(bre) <= abs(bim)
        if isinf(bre) && isinf(bim)
            r = sign(bre)/sign(bim)
        else
            r = bre / bim
        end
        den = bim + r*bre
        Complex((are*r + aim)/den, (aim*r - are)/den)
    else
        if isinf(bre) && isinf(bim)
            r = sign(bim)/sign(bre)
        else
            r = bim / bre
        end
        den = bre + r*bim
        complex((are + aim*r)/den, (aim - are*r)/den)
    end
end

inv{T<:Union(Float16,Float32)}(z::Complex{T}) =
    oftype(z, conj(complex128(z))/abs2(complex128(z)))

# robust complex division for double precision
# the first step is to scale variables if appropriate ,then do calculations
# in a way that avoids over/underflow (subfuncs 1 and 2), then undo the scaling.
# scaling variable s and other techniques
# based on arxiv.1210.4539
#             a + i*b
#  p + i*q = ---------
#             c + i*d
function /(z::Complex128, w::Complex128)
    a, b = reim(z); c, d = reim(w)
    half = 0.5
    two = 2.0
    ab = max(abs(a), abs(b))
    cd = max(abs(c), abs(d))
    ov = realmax(a)
    un = realmin(a)
    ϵ = eps(Float64)
    bs = two/(ϵ*ϵ)
    s = 1.0
    ab >= half*ov  && (a=half*a; b=half*b; s=two*s ) # scale down a,b
    cd >= half*ov  && (c=half*c; d=half*d; s=s*half) # scale down c,d
    ab <= un*two/ϵ && (a=a*bs; b=b*bs; s=s/bs      ) # scale up a,b
    cd <= un*two/ϵ && (c=c*bs; d=d*bs; s=s*bs      ) # scale up c,d
    abs(d)<=abs(c) ? ((p,q)=robust_cdiv1(a,b,c,d)  ) : ((p,q)=robust_cdiv1(b,a,d,c); q=-q)
    return Complex128(p*s,q*s) # undo scaling
end
function robust_cdiv1(a::Float64, b::Float64, c::Float64, d::Float64)
    r = d/c
    t = 1.0/(c+d*r)
    p = robust_cdiv2(a,b,c,d,r,t)
    q = robust_cdiv2(b,-a,c,d,r,t)
    return p,q
end
function robust_cdiv2(a::Float64, b::Float64, c::Float64, d::Float64, r::Float64, t::Float64)
    if r != 0
        br = b*r
        return (br != 0 ? (a+br)*t : a*t + (b*t)*r)
    else
        return (a + d*(b/c)) * t
    end
end

function inv(w::Complex128)
    c, d = reim(w)
    half = 0.5
    two = 2.0
    cd = max(abs(c), abs(d))
    ov = realmax(c)
    un = realmin(c)
    ϵ = eps(Float64)
    bs = two/(ϵ*ϵ)
    s = 1.0
    cd >= half*ov  && (c=half*c; d=half*d; s=s*half) # scale down c,d
    cd <= un*two/ϵ && (c=c*bs; d=d*bs; s=s*bs      ) # scale up c,d
    if abs(d)<=abs(c)
        r = d/c
        t = 1.0/(c+d*r)
        p = t
        q = -r * t
    else
        c, d = d, c
        r = d/c
        t = 1.0/(c+d*r)
        p = r * t
        q = -t
    end
    return Complex128(p*s,q*s) # undo scaling
end

function ssqs{T<:FloatingPoint}(x::T, y::T)
    k::Int = 0
    ρ = x*x + y*y
    if !isfinite(ρ) && (isinf(x) || isinf(y))
        ρ = convert(T, Inf)
    elseif isinf(ρ) || (ρ==0 && (x!=0 || y!=0)) || ρ<nextfloat(zero(T))/(2*eps(T)^2)
        m::T = max(abs(x), abs(y))
        k = m==0 ? m : exponent(m)
        xk, yk = ldexp(x,-k), ldexp(y,-k)
        ρ = xk*xk + yk*yk
    end
    ρ, k
end

function sqrt{T<:FloatingPoint}(z::Complex{T})
    x, y = reim(z)
    if x==y==0
        return Complex(zero(x),y)
    end
    ρ, k::Int = ssqs(x, y)
    if isfinite(x) ρ=ldexp(abs(x),-k)+sqrt(ρ) end
    if isodd(k)
        k = div(k-1,2)
    else
        k = div(k,2)-1
        ρ += ρ
    end
    ρ = ldexp(sqrt(ρ),k) #sqrt((abs(z)+abs(x))/2) without over/underflow
    ξ = ρ
    η = y
    if ρ != 0
        if isfinite(η) η=(η/ρ)/2 end
        if x<0
            ξ = abs(η)
            η = copysign(ρ,y)
        end
    end
    Complex(ξ,η)
end
sqrt(z::Complex) = sqrt(float(z))

# function sqrt(z::Complex)
#     rz = float(real(z))
#     iz = float(imag(z))
#     r = sqrt((hypot(rz,iz)+abs(rz))/2)
#     if r == 0
#         return Complex(zero(iz), iz)
#     end
#     if rz >= 0
#         return Complex(r, iz/r/2)
#     end
#     return Complex(abs(iz)/r/2, copysign(r,iz))
# end

cis(theta::Real) = Complex(cos(theta),sin(theta))
function cis(z::Complex)
    v = 1/exp(imag(z))
    Complex(v*cos(real(z)), v*sin(real(z)))
end

angle(z::Complex) = atan2(imag(z), real(z))

function log{T<:FloatingPoint}(z::Complex{T})
    const T0::T  = 0.7071067811865475
    const T1::T  = 1.25
    const T2::T  = 3
    const ln2::T = 0.6931471805599453
    x, y = reim(z)
    ρ, k = ssqs(x,y)
    ax = abs(x)
    ay = abs(y)
    if ax < ay
        θ, β = ax, ay
    else
        θ, β = ay, ax
    end
    if k==0 && T0 < β && (β <= T1 || ρ < T2)
        ρρ = log1p((β-1)*(β+1)+θ*θ)/2
    else
        ρρ = log(ρ)/2 + k*ln2
    end
    Complex(ρρ, angle(z))
end
log(z::Complex) = log(float(z))

# function log(z::Complex)
#     ar = abs(real(z))
#     ai = abs(imag(z))
#     if ar < ai
#         r = ar/ai
#         re = log(ai) + log1p(r*r)/2
#     else
#         if ar == 0
#             re = isnan(ai) ? ai : -inv(ar)
#         elseif isinf(ai)
#             re = oftype(ar,Inf)
#         else
#             r = ai/ar
#             re = log(ar) + log1p(r*r)/2
#         end
#     end
#     Complex(re, angle(z))
# end

log10(z::Complex) = log(z)/oftype(real(z),2.302585092994046)
log2(z::Complex) = log(z)/oftype(real(z),0.6931471805599453)

function exp(z::Complex)
    zr, zi = reim(z)
    if isfinite(zr) && !isfinite(zi) return Complex(oftype(zr, NaN), oftype(zi, NaN)) end
    if zr==Inf && zi==0 return Complex(zr, zi) end
    if zr==-Inf && !isfinite(zi) return Complex(-zero(zr), copysign(zero(zi), zi)) end
    if zr==Inf && !isfinite(zi) return Complex(-zr, oftype(zr, NaN)) end
    if isnan(zr) return Complex(zr, zi==0 ? zi : zr) end
    er = exp(zr)
    zi==0 && return Complex(er, zi)
    wr = er*(isfinite(zi) ? cos(zi) : zi)
    wi = er*(isfinite(zi) ? sin(zi) : zi)
    Complex(wr, wi)
end

function ^{T<:FloatingPoint}(z::Complex{T}, p::Complex{T})
    if p==2 #square
        zr, zi = reim(z)
        x = (zr-zi)*(zr+zi)
        y = 2zr*zi
        if isnan(x)
            if isinf(y)
                x = copysign(zero(T),zr)
            elseif isinf(zi)
                x = convert(T,-Inf)
            elseif isinf(zr)
                x = convert(T,Inf)
            end
        elseif isnan(y) && isinf(x)
            y = copysign(zero(T), y)
        end
        Complex(x,y)
    elseif z!=0
        if p!=0 && isinteger(p)
            rp = real(p)
            if rp < 0
                return power_by_squaring(inv(z), convert(Integer, -rp))
            else
                return power_by_squaring(z, convert(Integer, rp))
            end
        end
        exp(p*log(z))
    elseif p!=0 #0^p
        zero(z) #CHECK SIGNS
    else #0^0
        zer = copysign(zero(T),real(p))*copysign(zero(T),imag(z))
        Complex(one(T), zer)
    end
end

function exp2{T}(z::Complex{T})
    er = exp2(real(z))
    theta = imag(z) * log(convert(T, 2))
    Complex(er*cos(theta), er*sin(theta))
end

function exp10{T}(z::Complex{T})
    er = exp10(real(z))
    theta = imag(z) * log(convert(T, 10))
    Complex(er*cos(theta), er*sin(theta))
end

function ^{T<:Complex}(z::T, p::T)
    if isinteger(p)
        rp = real(p)
        if rp < 0
            return power_by_squaring(inv(float(z)), convert(Integer, -rp))
        else
            return power_by_squaring(float(z), convert(Integer, rp))
        end
    end
    pr, pim = reim(p)
    zr, zi = reim(z)
    r = abs(z)
    rp = r^pr
    theta = atan2(zi, zr)
    ntheta = pr*theta
    if pim != 0 && r != 0
        rp = rp*exp(-pim*theta)
        ntheta = ntheta + pim*log(r)
    end
    cosntheta = cos(ntheta)
    sinntheta = sin(ntheta)
    re, im = rp*cosntheta, rp*sinntheta
    if isinf(rp)
        if isnan(re)
            re = copysign(zero(re), cosntheta)
        end
        if isnan(im)
            im = copysign(zero(im), sinntheta)
        end
    end

    # apply some corrections to force known zeros
    if pim == 0
        ip = itrunc(pr)
        if ip == pr
            if zi == 0
                im = copysign(zero(im), im)
            elseif zr == 0
                if isodd(ip)
                    re = copysign(zero(re), re)
                else
                    im = copysign(zero(im), im)
                end
            end
        else
            dr = pr*2
            ip = itrunc(dr)
            if ip == dr && zi == 0
                if zr < 0
                    re = copysign(zero(re), re)
                else
                    im = copysign(zero(im), im)
                end
            end
        end
    end

    Complex(re, im)
end

^(z::Complex, n::Bool) = n ? z : one(z)
^(z::Complex, n::Integer) = z^Complex(n)

^{T<:FloatingPoint}(z::Complex{T}, n::Bool) = n ? z : one(z)  # to resolve ambiguity
^{T<:Integer}(z::Complex{T}, n::Bool) = n ? z : one(z)        # to resolve ambiguity

^{T<:FloatingPoint}(z::Complex{T}, n::Integer) =
    n>=0 ? power_by_squaring(z,n) : power_by_squaring(inv(z),-n)
^{T<:Integer}(z::Complex{T}, n::Integer) = power_by_squaring(z,n) # DomainError for n<0

function sin(z::Complex)
    zr, zi = reim(z)
    if !isfinite(zi) && zr == 0 return Complex(zr, zi) end
    if isnan(zr) && !isfinite(zi) return Complex(zr, zi) end
    if !isfinite(zr) && zi == 0 return Complex(oftype(zr, NaN), zi) end
    if !isfinite(zr) && isfinite(zi) return Complex(oftype(zr, NaN), oftype(zi, NaN)) end
    if !isfinite(zr) && !isfinite(zi) return Complex(zr, oftype(zi, NaN)) end
    Complex(sin(zr)*cosh(zi), cos(zr)*sinh(zi))
end

function cos(z::Complex)
    zr, zi = reim(z)
    if !isfinite(zi) && zr == 0
        return Complex(isnan(zi) ? zi : oftype(zi, Inf),
                       isnan(zi) ? zr : zr*-sign(zi))
    end
    if !isfinite(zr) && isinf(zi)
        return Complex(oftype(zr, Inf), oftype(zi, NaN))
    end
    if isinf(zr)
        return Complex(oftype(zr, NaN), zi==0 ? -copysign(zi, zr) : oftype(zi, NaN))
    end
    if isnan(zr) && zi==0 return Complex(zr, abs(zi)) end
    Complex(cos(zr)*cosh(zi), -sin(zr)*sinh(zi))
end

function tan(z::Complex)
    zr, zi = reim(z)
    w = tanh(Complex(-zi, zr))
    Complex(imag(w), -real(w))
end

function asin(z::Complex)
    zr, zi = reim(z)
    if isinf(zr) && isinf(zi)
        return Complex(copysign(pi/4, zr),zi)
    elseif isnan(zi) && isinf(zr)
        return Complex(zi, oftype(zr, Inf))
    end
    ξ = zr == 0       ? zr :
        !isfinite(zr) ? pi/2*sign(zr) :
        atan2(zr, real(sqrt(1-z)*sqrt(1+z)))
    η = asinh(copysign(imag(sqrt(conj(1-z))*sqrt(1+z)), imag(z)))
    Complex(ξ,η)
end

function acos{T<:FloatingPoint}(z::Complex{T})
    zr, zi = reim(z)
    if isnan(zr)
        if isinf(zi) return Complex(zr, -zi)
        else         return Complex(zr, zr) end
    elseif isnan(zi)
        if isinf(zr) return Complex(zi, abs(zr))
        elseif zr==0 return Complex(pi/2, zi)
        else         return Complex(zi, zi) end
    elseif zr==zi==0
        return Complex(pi/2, -zi)
    elseif zr==Inf && zi===0.0
        return Complex(zi, -zr)
    elseif zr==-Inf && zi===-0.0
        return Complex(oftype(zi, pi), -zr)
    end
    ξ = 2*atan2(real(sqrt(1-z)), real(sqrt(1+z)))
    η = asinh(imag(sqrt(conj(1+z))*sqrt(1-z)))
    if isinf(zr) && isinf(zi) ξ -= pi/4 * sign(zr) end
    Complex(ξ,η)
end
acos(z::Complex) = acos(float(z))

function atan(z::Complex)
    w = atanh(Complex(-imag(z),real(z)))
    Complex(imag(w),-real(w))
end

function sinh(z::Complex)
    zr, zi = reim(z)
    if isinf(zr) && isinf(zi) return Complex(zr, oftype(zi, NaN)) end
    w = sin(Complex(zi, zr))
    Complex(imag(w),real(w))
end

function cosh(z::Complex)
    zr, zi = reim(z)
    if isnan(zr) && zi==0 return Complex(zr, zi) end
    cos(Complex(-zi,zr))
end

function tanh{T<:FloatingPoint}(z::Complex{T})
    const Ω = prevfloat(typemax(T))
    ξ, η = reim(z)
    if isnan(ξ) && η==0 return Complex(ξ, η) end
    if 4*abs(ξ) > asinh(Ω) #Overflow?
        Complex(copysign(one(T),ξ),
                copysign(zero(T),η*(isfinite(η) ? sin(2*abs(η)) : one(η))))
    else
        t = tan(η)
        β = 1+t*t #sec(η)^2
        s = sinh(ξ)
        ρ = sqrt(1 + s*s) #cosh(ξ)
        if isinf(t)
            Complex(ρ/s,1/t)
        else
            Complex(β*ρ*s,t)/(1+β*s*s)
        end
    end
end
tanh(z::Complex) = tanh(float(z))

function asinh(z::Complex)
    w = asin(Complex(-imag(z),real(z)))
    Complex(imag(w),-real(w))
end

function acosh(z::Complex)
    zr, zi = reim(z)
    if isnan(zr) || isnan(zi)
        if isinf(zr) || isinf(zi)
            return Complex(oftype(zr, Inf), oftype(zi, NaN))
        else
            return Complex(oftype(zr, NaN), oftype(zi, NaN))
        end
    elseif zr==-Inf && zi===-0.0 #Edge case is wrong - WHY?
        return Complex(Inf, -pi)
    end
    ξ = asinh(real(sqrt(conj(z-1))*sqrt(z+1)))
    η = 2atan2(imag(sqrt(z-1)),real(sqrt(z+1)))
    if isinf(zr) && isinf(zi)
        η -= pi/4 * sign(zi) * sign(zr)
    end
    Complex(ξ, η)
end

function atanh{T<:FloatingPoint}(z::Complex{T})
    const Ω = prevfloat(typemax(T))
    const θ = sqrt(Ω)/4
    const ρ = 1/θ
    x, y = reim(z)
    ax = abs(x)
    ay = abs(y)
    if ax > θ || ay > θ #Prevent overflow
        if isnan(y)
            if isinf(x)
                return Complex(copysign(zero(x),x), y)
            else
                return Complex(real(1/z), y)
            end
        end
        if isinf(y)
            return Complex(copysign(zero(x),x), copysign(pi/2, y))
        end
        return Complex(real(1/z), copysign(pi/2, y))
    elseif ax==1
        if y == 0
            ξ = copysign(oftype(x,Inf),x)
            η = zero(y)
        else
            ym = ay+ρ
            ξ = log(sqrt(sqrt(4+y*y))/sqrt(ym))
            η = copysign(pi/2+atan(ym/2), y)/2
        end
    else #Normal case
        ysq = (ay+ρ)^2
        if x == 0
            ξ = x
        else
            ξ = log1p(4x/((1-x)^2 + ysq))/4
        end
        η = angle(Complex((1-x)*(1+x)-ysq, 2y))/2
    end
    Complex(ξ, η)
end
atanh(z::Complex) = atanh(float(z))

function lexcmp(a::Complex, b::Complex)
    c = cmp(real(a), real(b))
    c == 0 || return c
    cmp(imag(a), imag(b))
end

max_stars_repo_name: tobig/julia

max_issues_repo_name: tobig/julia

max_forks_repo_name: tobig/julia


text:
@testset "CircuitAnalysis tests" begin show_testset_section() #Scope for test data

using CMDimCircuits.CircuitAnalysis
import CMDimCircuits.CircuitAnalysis: DataTag
import CMDimCircuits.CircuitAnalysis: TCapacitance
import CMDimCircuits.CircuitAnalysis: TImpedance, TAdmittance

#==Input data
===============================================================================#
f = collect(1:3)*1e9
c = capacitance(5e-15)
j = im

#==Tests
===============================================================================#

@testset "Operations On Impedance Values" begin show_testset_description()
	fsng = 1e9
	ω = 2π*fsng
	@test c == TCapacitance(5.0e-15)
	@test_throws ArgumentError admittance(c) #Needs frequency
	@test TImpedance(1/(j*ω*c.v)) == impedance(c, f=fsng)
	@test TAdmittance(j*ω*c.v) == admittance(c, f=fsng)
end

@testset "Operations On Impedance Vectors" begin show_testset_description()
	rtol = 1e-4
	ω = 2π*f
	_ycap = j .* ω .* c.v
	ycap = admittance(c, f=f)
	@test ycap ≈ TAdmittance(_ycap) rtol = rtol
	a = -ycap
	b = TAdmittance(-(ycap.v))
	@test (-ycap) == TAdmittance(-(ycap.v))
	@test (-ycap).v == -(ycap.v)

	#@show ycap .* 5
	#@show 5 .* ycap
	#@show ycap .+ ycap
	#@show ycap ./ 5
	#try; 5 ./ ycap; @warn("Failed") #Would make impedance
	#catch e; @info("Fail successful."); end
end

@testset "Unit conversions" begin show_testset_description()
	rtol = 1e-4
	halfpwr = 3.010299956639812 #approx 3dB
	@test dB10(2) ≈ halfpwr rtol = rtol
	@test dB20(2) ≈ 2*halfpwr rtol = rtol

	#Decibels when provided power/voltage/current ratios
	@test dB(2,:Wratio) ≈ halfpwr rtol = rtol
	@test dB(2,:Vratio) ≈ 2*halfpwr rtol = rtol
	@test dB(2,:Iratio) ≈ 2*halfpwr rtol = rtol

	#Decibels reffered to 1W
	@test dBW(2,:W) ≈ halfpwr rtol = rtol
	@test dBW(2,:VRMS) ≈ 2*halfpwr rtol = rtol
	@test dBW(2,:Vpk) ≈ halfpwr rtol = rtol

	#Decibels reffered to 1mW
	@test dBm(2,:W) ≈ 30+halfpwr rtol = rtol
	@test dBm(2,:VRMS) ≈ 30+2*halfpwr rtol = rtol
	@test dBm(2,:Vpk) ≈ 30+halfpwr rtol = rtol

	#RMS voltage:
	@test VRMS(2,:W; R=50) ≈ sqrt(2*50) rtol = rtol
	@test VRMS(2,:Vpk) ≈ 2/sqrt(2) rtol = rtol

	#RMS current:
	@test IRMS(2,:W; R=50) ≈ sqrt(2/50) rtol = rtol
	@test IRMS(2,:Ipk) ≈ 2/sqrt(2) rtol = rtol

	#Peak voltage:
	@test Vpk(2,:W; R=50) ≈ sqrt(2*50)*sqrt(2) rtol = rtol
	@test Vpk(2,:VRMS) ≈ 2*sqrt(2) rtol = rtol

	#Peak current:
	@test Ipk(2,:W; R=50) ≈ sqrt(2/50)*sqrt(2) rtol = rtol
	@test Ipk(2,:IRMS) ≈ 2*sqrt(2) rtol = rtol
end

end


text:
using PyCall;

try
  pyimport("galgebra")
catch e
  run(PyCall.python_cmd(`-m pip install galgebra --user`))
end


text:
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/Materials.jl/blob/master/LICENSE

using Test, Tensors

E = 200.0e3
nu = 0.3
syield = 100.0
parameters = IdealPlasticParameterState(youngs_modulus = E,
                                        poissons_ratio = nu,
                                        yield_stress = syield)

mat = IdealPlastic(parameters=parameters)

times = [0.0]
loads = [0.0]
dt = 0.5
G = 0.5*E/(1+nu)
# vm = sqrt(3)*G*ga | ea = ga
ea = 2*syield/(sqrt(3)*G)
# Go to elastic border
push!(times, times[end]+dt)
push!(loads, loads[end] + ea*dt)
 # Proceed to plastic flow
push!(times, times[end]+dt)
push!(loads, loads[end] + ea*dt)
 # Reverse direction
push!(times, times[end]+dt)
push!(loads, loads[end] - ea*dt)
 # Continue and pass yield criterion
push!(times, times[end]+dt)
push!(loads, loads[end] - 2*ea*dt)
stresses = [copy(tovoigt(mat.variables.stress))]
for i=2:length(times)
    dtime = times[i]-times[i-1]
    dstrain31 = loads[i]-loads[i-1]
    dstrain = [0.0, 0.0, 0.0, 0.0, 0.0, dstrain31]
    dstrain_ = fromvoigt(SymmetricTensor{2,3,Float64}, dstrain; offdiagscale=2.0)
    ddrivers = IdealPlasticDriverState(time = dtime, strain = dstrain_)
    #mat.dtime = dtime
    #mat.dstrain = dstrain
    mat.ddrivers = ddrivers
    integrate_material!(mat)
    update_material!(mat)
    push!(stresses, copy(tovoigt(mat.variables.stress)))
end

for i in 1:length(times)
    @test isapprox(stresses[i][1:5], zeros(5); atol=1e-6)
end
s31 = [s[6] for s in stresses]

s31_expected = [0.0, syield/sqrt(3.0), syield/sqrt(3.0), 0.0, -syield/sqrt(3.0)]
@test isapprox(s31, s31_expected; rtol=1.0e-2)


text:
"""
    File containing all the conventions used to name objects.
"""
bus_name(id_bus::Int64) = "BUS_$id_bus"
get_busid(busname::String) = busname[5:end]
basecase_scenario_name() = "" #NOTE: for Matpower "BaseCase" for GOC

function variable_name(varname::String, bus::String, elemid::String, scenario::String)
    if elemid == ""
        if basecase_scenario_name() == ""
            return "$(varname)_$(get_busid(bus))"
        else
            return "$(scenario)_$(get_busid(bus))_$(varname)"
        end
    else
        if basecase_scenario_name() == ""
            return "$(elemid)_$(varname)_$(get_busid(bus))"
        else
            return "$(scenario)_$(get_busid(bus))_$(elemid)_$(varname)"
        end
    end
end

function variable_name(varname::String, link::Link, elemid::String, scenario::String)
    if elemid == ""
        return "$(scenario)_$(get_busid(link.orig))-$(get_busid(link.dest))_$(varname)"
    else
        return "$(scenario)_$(get_busid(link.orig))-$(get_busid(link.dest))_$(elemid)_$(varname)"
    end
end

function cstrname_nodal_balance(cstrnames::SortedSet{String}, scenario::String, bus::String)
    cstr = ""
    for cstrname in cstrnames
        cstr = "$(cstr)-$cstrname"
    end

    if cstr == ""
      cstr = "-LOAD"
    end

    return "$(scenario)_$(get_busid(bus))_BALANCE$(cstr)"
end

function get_cstrname(scenario::String, bus::String, elemid::String, cstrname::String)
    if elemid == ""
        return "$(scenario)_$(get_busid(bus))_$(cstrname)"
    else
        return "$(scenario)_$(get_busid(bus))_$(elemid)_$(cstrname)"
    end
end

function get_cstrname(scenario::String, link::Link, elemid::String, cstrname::String)
    if elemid == ""
        return "$(scenario)_$(get_busid(link.orig))-$(get_busid(link.dest))_$(cstrname)"
    else
        return "$(scenario)_$(get_busid(link.orig))-$(get_busid(link.dest))_$(elemid)_$(cstrname)"
    end
end

### GOC conventions
scenarioname(id_contingency::Int) = "Scen$id_contingency"

# nodal element names
volt_name() = "Volt"
generator_name(gen_id) = "Gen$gen_id"
load_name(id_load) = "Load$id_load"
shunt_name(id_shunt) = "Shunt$id_shunt"

get_delta_varname(scenario::String) = "$(scenario)_Delta"
get_binInf_varname(scenario1::String, scenario2::String, bus::String) = "BinVolt_$(get_busid(bus))_$(scenario1)_inf_$(scenario2)"
get_binEq_varname(scenario1::String, scenario2::String, bus::String) = "BinVolt_$(get_busid(bus))_$(scenario1)_eq_$(scenario2)"

# constraint names
get_VoltM_cstrname() = "VOLTM"
get_ShuntDef_cstrname() = "ShuntDef"
get_LoadDef_cstrname() = "LoadDef"
get_GenBounds_cstrname() = "GenBounds"
get_NullImpVolt_cstrname() = "NullImpVolt"

get_VoltBinDef_upper() = "BinDef-upper"
get_VoltBinDef_lower() = "BinDef-lower"
get_VoltBinDef_complement() = "BinDef-compl"

get_CC_active_cstrname() = "CC-Pgen"
get_CC_reactiveupper_cstrname() = "CC-Qgen-upper"
get_CC_reactivelower_cstrname() = "CC-Qgen-lower"

get_Smax_orig_cstrname() = "Smax-orig"
get_Smax_dest_cstrname() = "Smax-dest"

get_Imax_orig_cstrname() = "Imax-orig"
get_Imax_dest_cstrname() = "Imax-dest"

get_GOC_Volt_ϵ() = 1e-6
get_GOC_BigM() = 1e1

##node elems

##link elems
nullimpedance_notransformer_name(branch_id) = "NullImp_notransfo_$branch_id"
linepi_withtransformer_name(branch_id) = "Lineπ_transfo_$branch_id"
nullimpedance_withtransformer_name(branch_id) = "NullImp_transfo_$branch_id"
linepi_notransformer_name(branch_id) = "Lineπ_notransfo_$branch_id"


text:
# AUTO GENERATED FILE - DO NOT EDIT

export dashbio_fornacontainer

"""
    dashbio_fornacontainer(;kwargs...)

A FornaContainer component.
FornaContainer is a force-directed graph that is used to visualize
the secondary structure of biomolecules. It is based on the fornac
library (https://github.com/ViennaRNA/fornac).
Keyword arguments:
- `id` (String; optional): The ID of this component, used to identify dash components in
callbacks. The ID needs to be unique across all of the
components in an app.
- `allowPanningAndZooming` (Bool; optional): Allow users to zoom in and pan the display. If this is enabled,
then pressing the 'c' key on the keyboard will center the view.
- `colorScheme` (a value equal to: 'sequence', 'structure', 'positions', 'custom'; optional): The color scheme that is used to color the nodes.
- `customColors` (optional): The custom colors used to color the nodes if the 'custom'
option is chosen for the `colorScheme` prop.
For example, if the domain is `[0, 20]`, the range is
`['yellow', 'red']`, and the dictionary specified in
'colorValues' that corresponds to a molecule is `{'6': 10}`,
the sixth nucleotide in that molecule will have a color that is
perfectly in between yellow and red (i.e., orange), since 10 is
perfectly in between 0 and 20.. customColors has the following type: lists containing elements 'domain', 'range', 'colorValues'.
Those elements have the following types:
  - `domain` (Array of Reals; optional): The limits for the color scale. This is used with the range
specified in `range` to calculate the color of a given
nucleotide, based on the number that it is assigned.
  - `range` (Array of Strings; optional): The range of colors that will be used in conjunction with
the `domain` prop.
  - `colorValues` (Dict with Strings as keys and values of type Dict with Strings as keys and values of type String | Real; optional): A dictionary which contains keys, each of which are either
an empty string (`''`) or the name of a molecule that has
been defined in the `name` prop in the `options` for a
sequence in the `sequences` property.
The value corresponding to the key that is an empty string
(if that key exists) is a "default" color scheme that will
be applied first, and can be overridden by the color
schemes defined for molecule-specific keys. The
aforementioned color schemes each take the form of a
dictionary in which the keys are the nucleotide positions
and the values are either a) numbers to be normalized with
respect to the scale defined in `domain` (so that their
color will be calculated), or b) direct string
representations of colors.
- `height` (Real; optional): The height (in px) of the container in which the molecules will
be displayed.
- `nodeFillColor` (String; optional): The fill color for all of the nodes. This will override any
color scheme defined in colorScheme.
- `sequences` (optional): The molecules that will be displayed.. sequences has the following type: Array of lists containing elements 'sequence', 'structure', 'options'.
Those elements have the following types:
  - `sequence` (String; required): A string representing the RNA nucleotide sequence of
the RNA molecule.
  - `structure` (String; required): A dot-bracket string
(https://software.broadinstitute.org/software/igv/RNAsecStructure)
that specifies the secondary structure of the RNA
molecule.
  - `options` (optional): Additional options to be applied to the rendering of
the RNA molecule.. options has the following type: lists containing elements 'applyForce', 'circularizeExternal', 'labelInterval', 'name', 'avoidOthers'.
Those elements have the following types:
  - `applyForce` (Bool; optional): Indicate whether the force-directed layout will be
applied to the displayed molecule. Enabling this
option allows users to change the layout of the
molecule by selecting and dragging the individual
nucleotide nodes. True by default.
  - `circularizeExternal` (Bool; optional): This only makes sense in connection with the
applyForce argument. If it's true, the external
loops will be arranged in a nice circle. If false,
they will be allowed to flop around as the force
layout dictates. True by default.
  - `labelInterval` (Real; optional): Change how often nucleotide numbers are labelled
with their number. 10 by default.
  - `name` (String; optional): The molecule name; this is used in custom color
scales.
  - `avoidOthers` (Bool; optional): Whether or not this molecule should "avoid" other
molecules in the map.s
- `width` (Real; optional): The width (in px) of the container in which the molecules will
be displayed.
"""
function dashbio_fornacontainer(; kwargs...)
        available_props = Symbol[:id, :allowPanningAndZooming, :colorScheme, :customColors, :height, :nodeFillColor, :sequences, :width]
        wild_props = Symbol[]
        return Component("dashbio_fornacontainer", "FornaContainer", "dash_bio", available_props, wild_props; kwargs...)
end


text:
"""
Light ray structure, storing origin and direction of the ray.
The direction needs not be normalized.
"""
struct Ray
    origin::Vector
    direction::Vector
end

"""
    point_at_parameter(ray, t)

Compute point on ray at parameter `t`.
"""
point_at_parameter(ray::Ray, t) = ray.origin + t*ray.direction