If e is identically a rational constant p/q (a multivariate rational * identity, e.g. b/(b·(bc/(bc−ad)) − a·(bd/(bc−ad))) = 1), return that * constant; else null. Sample-then-verify: a numeric sample guesses the * constant, polynomial expansion verifies the identity exactly.
(e: Expression)
| 201 | let t = rs[i].num; |
| 202 | for (let j = 0; j < rs.length; j++) if (j !== i) t = t.mul(rs[j].den); |
| 203 | num = num.add(t); |
| 204 | } |
| 205 | return { num, den }; |
| 206 | } |
| 207 | case 'Subtract': { |
| 208 | const u = asNumDen(ops![0]); |
| 209 | const v = asNumDen(ops![1]); |
| 210 | return { |
| 211 | num: u.num.mul(v.den).sub(v.num.mul(u.den)), |
| 212 | den: u.den.mul(v.den), |
| 213 | }; |
| 214 | } |
| 215 | case 'Power': { |
| 216 | const k = ops![1].re; |
| 217 | if ( |
| 218 | ops![1].isInteger && |
| 219 | typeof k === 'number' && |
| 220 | Number.isInteger(k) && |
| 221 | k !== 0 && |
| 222 | Math.abs(k) <= 6 |
| 223 | ) { |
| 224 | const r = asNumDen(ops![0]); |
| 225 | if (k > 0) return { num: r.num.pow(k), den: r.den.pow(k) }; |
| 226 | return { num: r.den.pow(-k), den: r.num.pow(-k) }; |
| 227 | } |
| 228 | return { num: e, den: ce.One }; |
| 229 | } |
| 230 | default: |
| 231 | return { num: e, den: ce.One }; |
| 232 | } |
| 233 | } |
| 234 | |
| 235 | /** If e is identically a rational constant p/q (a multivariate rational |
| 236 | * identity, e.g. b/(b·(bc/(bc−ad)) − a·(bd/(bc−ad))) = 1), return that |
| 237 | * constant; else null. Sample-then-verify: a numeric sample guesses the |