Rubi GeneralizedBinomialParts → {a,b,n,q}: u ≡ a·x^q + b·x^n, PosQ[n−q]
(u: Expression, x: string)
| 1928 | ? ce.function('Multiply', [ |
| 1929 | ce.function('Power', [ce.symbol(x), ce.number(m)]), |
| 1930 | R, |
| 1931 | ]) |
| 1932 | : R; |
| 1933 | return n.div(denExpr); |
| 1934 | } |
| 1935 | |
| 1936 | function functionOfLog( |
| 1937 | u: Expression, |
| 1938 | x: string |
| 1939 | ): { f: Expression; v: Expression; n: Expression } | null { |
| 1940 | const ce = u.engine; |
| 1941 | u = cancelCommonXPower(u, x); |
| 1942 | // (vAcc,nAcc) accumulate the shared log argument and exponent; vAcc===null |
| 1943 | // is Rubi's `False` sentinel meaning "not yet bound". |
| 1944 | let vAcc: Expression | null = null; |
| 1945 | let nAcc: Expression | null = null; |
| 1946 | const rec = (e: Expression): Expression | null => { |
| 1947 | // AtomQ[u]: a constant passes through; the bare integration variable |
| 1948 | // (u===x) cannot be expressed as a function of a log → False. |
| 1949 | if (e.ops == null || e.ops.length === 0) return e.symbol === x ? null : e; |
| 1950 | const head = e.operator; |
| 1951 | if (CALCULUS_FNS.has(head)) return null; // CalculusQ[u] → False |
| 1952 | // Log[a·x^n] leaf (zero constant term): substitute → x, record (v,n). |
| 1953 | if (head === 'Ln' || (head === 'Log' && e.ops.length === 1)) { |
| 1954 | const bp = binomialPartsX(e.ops[0], x); |
| 1955 | if (bp !== null && (bp.a.isSame(0) || zeroQ(bp.a))) { |
| 1956 | if (vAcc === null || e.ops[0].isSame(vAcc)) { |
| 1957 | vAcc = e.ops[0]; |
| 1958 | nAcc = bp.n; |
| 1959 | return ce.symbol(x); |
| 1960 | } |
| 1961 | return null; // a second, distinct log argument → False |
| 1962 | } |
| 1963 | // otherwise fall through: recurse structurally into the log's argument |
| 1964 | } |
| 1965 | // Map FunctionOfLog over the operands, threading (v,n), reconstruct head. |
| 1966 | const parts: Expression[] = []; |
| 1967 | for (const op of e.ops) { |
| 1968 | const r = rec(op); |
| 1969 | if (r === null) return null; // Throw[False] |
| 1970 | parts.push(r); |
| 1971 | } |
| 1972 | return ce.function(head, parts); |
| 1973 | }; |
| 1974 | const f = rec(u); |
| 1975 | if (f === null || vAcc === null) return null; |
no test coverage detected