diff --git a/BREAKING-CHANGES.md b/BREAKING-CHANGES.md
index 59087d3a0..5ec2f6700 100644
--- a/BREAKING-CHANGES.md
+++ b/BREAKING-CHANGES.md
@@ -203,6 +203,20 @@ compared everywhere with its value at one positive point
| `"asin(sqrt(1+b*x^2))^n/sqrt(1+b*x^2)".ToEntity().Integrate("x")` | `integral(...)` | 136 characters |
| `"acos(sqrt(1+b*x^2))^n/sqrt(1+b*x^2)".ToEntity().Integrate("x")` | `integral(...)` | 137 characters |
+### A power of a sum beside its derivative is read with the logarithms in it as factors
+
+**Answers where there were none.** `(a m x^m + b n q ln(c x^n)^(q - 1))/(x (a x^m + b ln(c x^n)^q))` was declined, and so
+were five more of Rubi's 3.5, the sum's square and the powers of `a x^2 + b x ln(c x^n)^2` among them. Each is a
+constant times `g' g^k` for a sum `g`, but the derivative of `ln(c x^n)^q` is written `q ln(c x^n)^(q - 1) c n x^(n - 1)/(c x^n)`,
+which nothing brought down to the `n q ln(c x^n)^(q - 1)/x` the integrand writes. The terms are now read as a
+coefficient times powers of x and of the other functions of x in them, and a power of x common to the sum is taken
+out of it ([#233](https://github.com/asc-community/AngouriMath/issues/233)).
+
+| Input | Was (2.5.0) | Now |
+|---|---|---|
+| `"(a*m*x^m+b*n*q*ln(c*x^n)^(q-1))/(x*(a*x^m+b*ln(c*x^n)^q))".ToEntity().Integrate("x")` | `integral(...)` | `ln(a x^m + b ln(c x^n)^q)` |
+| `"(a*(m-1)*x^(m-1)+b*n*q*ln(c*x^n)^(q-1))/(a*x^m+b*x*ln(c*x^n)^q)".ToEntity().Integrate("x")` | `integral(...)` | `ln(a x^(m - 1) + b ln(c x^n)^q)` |
+
### A rational evaluated at a higher precision than before has all of its digits
**More digits where there were a hundred.** A rational kept its decimal value in the precision current when it was
diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
index c372e4b2b..6986f050e 100644
--- a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
+++ b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
@@ -34500,6 +34500,161 @@ Entity Named(Entity value)
}
}
+ ///
+ /// A power of a sum beside a constant multiple of the sum's derivative, with symbolic powers
+ /// about: c g' g^k is c g^(k + 1)/(k + 1), and c ln(g) for k = -1.
+ /// Each term is read as a coefficient times a power of x times powers of the other
+ /// functions of x in it, the powers of each merged, so that
+ /// d/dx ln(c x^n)^q = q n ln(c x^n)^(q - 1)/x is matched against
+ /// b n q ln(c x^n)^(q - 1)/x as written. Where the terms do not match, a power of
+ /// x common to every term of the sum is taken out of it into the rest:
+ /// a x^m + b x ln(c x^n)^q is x (a x^(m - 1) + b ln(c x^n)^q). Rubi's 3.5.
+ /// https://github.com/asc-community/AngouriMath/issues/233
+ ///
+ ///
+ /// reads only powers of
+ /// x, and the substitution's simplification of the quotient by du/dx never
+ /// brings c n x^(n - 1)/(c x^n) down to n/x. Only where a power is symbolic:
+ /// otherwise the substitution answers it.
+ ///
+ internal static Entity? SolveAPowerOfASumBesideItsDerivativeWithSymbolicPowers(Entity expr, Entity.Variable x)
+ {
+ if (!expr.Nodes.Any(node => node is Powf(var @base, var exponent) && @base.ContainsNode(x) && !exponent.ContainsNode(x) && exponent.Vars.Any()))
+ return null;
+ var factors = FactorsOfTheIntegrand(expr);
+ for (var chosen = 0; chosen < factors.Count; chosen++)
+ {
+ var (factor, underneath) = factors[chosen];
+ var (sum, power) = factor is Powf(var b, var e) && !e.ContainsNode(x) ? (b, e) : (factor, (Entity)Number.Integer.One);
+ if (sum is not (Sumf or Minusf) || !sum.ContainsNode(x) || power.Evaled is not Number.Rational k)
+ continue;
+ if (underneath)
+ k = (Number.Rational)(-k);
+ // The rest: at most one sum above the bar, every other factor one term.
+ Entity? restSum = null;
+ Entity monomial = Number.Integer.One;
+ var readable = true;
+ for (var other = 0; other < factors.Count && readable; other++)
+ {
+ if (other == chosen)
+ continue;
+ var (f, below) = factors[other];
+ if (!below && restSum is null && f is Sumf or Minusf && f.ContainsNode(x))
+ restSum = f;
+ else if (f is Sumf or Minusf && f.ContainsNode(x))
+ readable = false;
+ else
+ monomial = below ? monomial / f : monomial * f;
+ }
+ if (!readable)
+ continue;
+ var rest = (restSum is null ? new[] { monomial } : Sumf.LinearChildren(restSum).Select(term => term * monomial)).ToList();
+ if (Matched(rest, sum, x) is { } constant)
+ return Answer(constant, sum, k);
+ // A power of x common to the sum's terms, taken out: x^j g, so that c x^(j k) g'... is read against g.
+ if (Terms(Sumf.LinearChildren(sum), x) is not { } terms)
+ continue;
+ foreach (var common in terms.Select(t => t.Exponent).Where(e => e.Evaled is Number.Integer { IsZero: false }).Distinct().ToList())
+ {
+ Entity reduced = Number.Integer.Zero;
+ foreach (var t in terms)
+ {
+ var exponent = (t.Exponent - common).InnerSimplified;
+ Entity written = t.Atoms.Aggregate(t.Coefficient, (product, atom) => product * MathS.Pow(atom.Base, atom.Power));
+ if (exponent.Evaled is not Number.Complex { IsZero: true })
+ written *= exponent == Number.Integer.One ? x : MathS.Pow(x, exponent);
+ reduced = reduced == Number.Integer.Zero ? written : reduced + written;
+ }
+ // x^(common k) moves into the rest.
+ var moved = MathS.Pow(x, (common * k).InnerSimplified);
+ if (Matched(rest.Select(term => term * moved).ToList(), reduced, x) is { } c)
+ return Answer(c, reduced, k);
+ }
+ }
+ return null;
+
+ static Entity Answer(Entity constant, Entity sum, Number.Rational k)
+ => k == Number.Integer.MinusOne
+ ? constant * MathS.Ln(sum)
+ : constant / (k + 1) * MathS.Pow(sum, (Entity)(k + 1));
+
+ // The constant c with the rest's terms c times the sum's derivative's, or null.
+ static Entity? Matched(List rest, Entity sum, Entity.Variable x)
+ {
+ var derivative = sum.Differentiate(x);
+ if (derivative is Providedf(var bare, _))
+ derivative = bare;
+ if (Terms(rest, x) is not { } above || Terms(Sumf.LinearChildren(derivative), x) is not { } below || above.Count != below.Count)
+ return null;
+ Entity? constant = null;
+ foreach (var term in above)
+ {
+ var matching = below.Where(other => SameMonomial(term, other)).ToList();
+ if (matching.Count != 1)
+ return null;
+ var ratio = Bare((term.Coefficient / matching[0].Coefficient).Simplify());
+ if (ratio.ContainsNode(x) || ratio.Nodes.Any(node => node == MathS.NaN))
+ return null;
+ if (constant is null)
+ constant = ratio;
+ else if (Bare((constant - ratio).Simplify()) != Number.Integer.Zero)
+ return null;
+ }
+ return constant;
+ }
+
+ static bool SameMonomial((Entity Coefficient, Entity Exponent, List<(Entity Base, Entity Power)> Atoms) one,
+ (Entity Coefficient, Entity Exponent, List<(Entity Base, Entity Power)> Atoms) other)
+ => Bare((one.Exponent - other.Exponent).Simplify()) == Number.Integer.Zero
+ && one.Atoms.Count == other.Atoms.Count
+ && one.Atoms.All(atom => other.Atoms.Any(theirs => theirs.Base == atom.Base && Bare((theirs.Power - atom.Power).Simplify()) == Number.Integer.Zero));
+
+ static Entity Bare(Entity simplified) => simplified is Providedf(var inner, _) ? inner : simplified;
+
+ // Each term as a coefficient free of x, a power of x, and powers of other functions of
+ // x, each base's powers merged; null where a factor is a sum holding x.
+ static List<(Entity Coefficient, Entity Exponent, List<(Entity Base, Entity Power)> Atoms)>? Terms(IEnumerable terms, Entity.Variable x)
+ {
+ var read = new List<(Entity, Entity, List<(Entity, Entity)>)>();
+ foreach (var term in terms)
+ {
+ var (numerator, denominator) = Functions.SingleQuotient.Of(term is Providedf(var t, _) ? t : term);
+ Entity exponent = Number.Integer.Zero;
+ Entity coefficient = Number.Integer.One;
+ var atoms = new List<(Entity Base, Entity Power)>();
+ foreach (var (side, underneath) in new[] { (numerator, false), (denominator, true) })
+ foreach (var factor in Mulf.LinearChildren(side))
+ {
+ if (!factor.ContainsNode(x))
+ {
+ coefficient = underneath ? coefficient / factor : coefficient * factor;
+ continue;
+ }
+ var (@base, power) = factor is Powf(var b, var e) && !e.ContainsNode(x) ? (b, e) : (factor, (Entity)Number.Integer.One);
+ if (underneath)
+ power = -power;
+ if (@base == x)
+ exponent += power;
+ else if (@base is Sumf or Minusf)
+ return null;
+ else
+ {
+ var at = atoms.FindIndex(atom => atom.Base == @base);
+ if (at < 0)
+ atoms.Add((@base, power));
+ else
+ atoms[at] = (@base, atoms[at].Power + power);
+ }
+ }
+ // A term the derivative writes as 0 times something is no term.
+ if (coefficient.InnerSimplified.Evaled is Number.Complex { IsZero: true })
+ continue;
+ read.Add((coefficient, exponent.InnerSimplified, atoms.Select(atom => (atom.Base, atom.Power.InnerSimplified)).ToList()));
+ }
+ return read;
+ }
+ }
+
///
/// An exponential of a polynomial beside the polynomial's derivative, with the rest a
/// function of the polynomial: G^P k P' f(P) is k G^u f(u) under u = P.
diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs b/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
index 3ceb0c6f3..2f5e7b9b9 100644
--- a/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
+++ b/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
@@ -1100,6 +1100,8 @@ private static Entity WithItsPiecewiseSumsCombined(Entity expr)
// A logarithmic derivative the substitution above could not read for a symbol in
// an exponent: `(x^(n-1) - 1)/(x^n - n x)`.
if ((answer = IndefiniteIntegralSolver.SolveALogarithmicDerivativeWithASymbolicExponent(expr, x)) is { }) return answer;
+ // And a power of a sum beside its derivative, with functions of x besides powers of it in the terms.
+ if ((answer = IndefiniteIntegralSolver.SolveAPowerOfASumBesideItsDerivativeWithSymbolicPowers(expr, x)) is { }) return answer;
// After the general substitution rather than inside it, because the general one
// divides by du/dx and asks what is left, and that question loses the shape here:
// sqrt(tan(x)) over the derivative of sqrt(tan(x)) simplifies to sin(2x), in which
diff --git a/Sources/Tests/UnitTests/Calculus/APowerOfASumBesideItsDerivativeWithSymbolicPowersIntegralTest.cs b/Sources/Tests/UnitTests/Calculus/APowerOfASumBesideItsDerivativeWithSymbolicPowersIntegralTest.cs
new file mode 100644
index 000000000..9cd089057
--- /dev/null
+++ b/Sources/Tests/UnitTests/Calculus/APowerOfASumBesideItsDerivativeWithSymbolicPowersIntegralTest.cs
@@ -0,0 +1,30 @@
+//
+// Copyright (c) 2019-2026 Angouri.
+// AngouriMath is licensed under MIT.
+// Details: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.
+// Website: https://am.angouri.org.
+//
+
+using AngouriMath.Extensions;
+using Xunit;
+
+namespace AngouriMath.Tests.Calculus
+{
+ ///
+ /// A power of a sum beside its derivative, where the terms hold a symbolic power of a
+ /// logarithm: the derivative of ln(c x^n)^q is written q ln(c x^n)^(q - 1) c n x^(n - 1)/(c x^n),
+ /// which nothing brought down to the n q ln(c x^n)^(q - 1)/x the integrand writes. They were
+ /// declined. Rubi's 3.5.
+ /// #233
+ ///
+ [Trait("Area", "Calculus")]
+ public sealed class APowerOfASumBesideItsDerivativeWithSymbolicPowersIntegralTest
+ {
+ [Theory]
+ [InlineData("(a*m*x^m + b*n*q*ln(c*x^n)^(q - 1))*(a*x^m + b*ln(c*x^n)^q)/x", "1/2*(a*x^m + b*ln(c*x^n)^q)^2")]
+ [InlineData("(a*m*x^m + b*n*q*ln(c*x^n)^(q - 1))/(x*(a*x^m + b*ln(c*x^n)^q))", "ln(a*x^m + b*ln(c*x^n)^q)")]
+ [InlineData("(a*(m - 1)*x^(m - 1) + b*n*q*ln(c*x^n)^(q - 1))/(a*x^m + b*x*ln(c*x^n)^q)", "ln(a*x^(m - 1) + b*ln(c*x^n)^q)")]
+ public void TheSumToTheNextPower(string integrand, string expected)
+ => Assert.Equal(expected.ToEntity().InnerSimplified, integrand.ToEntity().Integrate("x").Substitute("C", 0).InnerSimplified);
+ }
+}