Download or view powerTransformations.frink in plain text format
// The dependency on LambertW.frink brings in dependencies on
// ArbitraryPrecision.frink and pi.frink. You can comment
// out the "use" statement below without problems; you just won't be able
// to get a numerical result for the LambertW function; it will just give
// a symbolic result.
use LambertW.frink
/** This contains solvers for equations containing exponents. It is generally
only intended for real-valued arguments and will not always find all
solutions.
*/
transformations power
{
// Turn exp[x] into e^x
exp[_x] <-> e^_x
// Solve x^y === z for y
// or, more generally, this solves
// (a x)^((k y)^n) === z for y
solve[((_a:1) _x) ^ (((_k:1) _y)^(_n:1)) === _z, _y] :: freeOf[_k, _y] && freeOf[_a, _y] && freeOf[_n, _y] && freeOf[_z, _y] <-> solve[_y === (ln[_z] / (ln[_a _x])^(1/_n)) / _k, _y]
// Solve c a^y b^y === z for y
solve[(_c:1) _a^_y _b^_y === _z, _y] :: freeOf[_a, _y] && freeOf[_b, _y] && freeOf[_c, _y] && freeOf[_z, _y] <-> solve[_y === ln[_z / _c] / (ln[_a] + ln[_b]), _y]
// Solve x^y === z for x for irrational exponents. (Rational exponents
// are solved better in solvingTransformations.frink )
solve[_x ^ _y === _z, _x] :: freeOf[_z, _x] && ! isInteger[_y] && ! isRational[_y] <-> solve[_x === _z^(1/_y), _x]
// Solve ln[a] === b when a contains the variable y we're solving for.
// This is only valid for the reals or complex
// numbers where -pi < Im[y] <= pi
// Basically, we take the exp() of both sides.
solve[ln[_a] === _b, _y] :: freeOf[_b, _y] and expressionContains[_a, _y] <-> solve[_a === e^_b, _y]
// Solve log[a] === b when a contains the variable y we're solving for.
// Basically, we take the 10^ of both sides.
solve[log[_a] === _b, _y] :: freeOf[_b, _y] and expressionContains[_a, _y] <-> solve[_a === 10^_b, _y]
// Solve _b^_a = x when a contains the variable y we're solving for.
// This does not find all solutions.
// Basically, take log of both sides to base _b.
// The exclusions for integer and rational arguments are because these
// are better solved (finding more solutions) by the routines in
// solvingTransformations.frink
solve[_b^_a === _x, _y] :: freeOf[_x, _y] and freeOf[_b, _y] and expressionContains[_a, _y] && ! isInteger[_a] && ! isRational[_a] <-> solve[_a === ln[_x] / ln[_b], _y]
// Solve _b^_a = x when b contains the variable y we're solving for.
// This does not find all solutions.
// Basically, take log of both sides to base _b.
// The exclusions for integer and rational arguments are because these
// are better solved (finding more solutions) by the routines in
// solvingTransformations.frink
solve[_b^_a === _x, _y] :: freeOf[_x, _y] and freeOf[_a, _y] and expressionContains[_b, _y] && ! isInteger[_a] && ! isRational[_a] <-> solve[ln[_b] === ln[_x] / _a, _y]
// Solve generalizations of a = n / ln[n] for n which include
// a = n / ln[c n]
// a = n / ln[c n^x]
// a = n^y / ln[c n^x]
// The exponents y and x can be negative, which indicates division by n.
// This requires the Lambert W function which is not yet part of core
// Frink but is defined in LambertW.frink which has dependencies on
// ArbitraryPrecision.frink and sqrtWayne.frink.
solve[_n^(_y:1) / ln[(_c:1) _n^(_x:1)] === _a, _n] :: freeOf[_c, _n] and freeOf[_y, _n] and freeOf[_x, _n] <-> [ solve[_n === (-((_a*_x*LambertW[-(((_c^(-1))^(_y/_x)*_y)/(_a*_x))])/_y))^_y^(-1), _n], solve[_n === (-((_a*_x*LambertW1[-(((_c^(-1))^(_y/_x)*_y)/(_a*_x))])/_y))^_y^(-1), _n]]
// Solve generalizations of a = n ln[n] for n which include
// a = n ln[c n]
// a = n ln[c n^x]
// a = n^y ln[c n^x]
// The exponents y and x can be negative, which indicates division by n.
// This requires the Lambert W function which is not yet part of core
// Frink but is defined in LambertW.frink which has dependencies on
// ArbitraryPrecision.frink and sqrtWayne.frink.
solve[_n^(_y:1) ln[(_c:1) _n^(_x:1)] === _a, _n] :: freeOf[_c, _n] and freeOf[_x, _n] and freeOf[_y, _n] <-> [ solve[_n === ((_a _y)/(_x LambertW[(_a _y)/((_c^(-_x^(-1)))^_y * _x)]))^_y^(-1), _n], solve[_n === ((_a _y)/(_x LambertW1[(_a _y)/((_c^(-_x^(-1)))^_y * _x)]))^_y^(-1), _n]]
// Solve generalizations of z = w e^w for w which include
// z = w e^(d w)
// and even
// w^x e^(d w^y)
// This requires the Lambert W function which is not yet part of core
// Frink but is defined in LambertW.frink which has dependencies on
// ArbitraryPrecision.frink and sqrtWayne.frink.
// This is currently commented out because it is solved by the more general
// rule below.
// solve[_w^(_x:1) e^((_d:1) _w^(_y:1)) === _z, _w] :: freeOf[_d, _w] and freeOf[_y,_w] and freeOf[_x, _w] <-> solve[_w === (_x LambertW[_d _y _z^(_y / _x) / _x] / (_d _y))^(1/_y), _w]
// Solve generalizations of z = w b^w for w which include
// z = w b^(d w)
// and even
// w^x b^(d w^y)
// This requires the Lambert W function which is not yet part of core
// Frink but is defined in LambertW.frink which has dependencies on
// ArbitraryPrecision.frink and sqrtWayne.frink.
solve[_w^(_x:1) _b^((_d:1) _w^(_y:1)) === _z, _w] :: freeOf[_d, _w] and freeOf[_y,_w] and freeOf[_z, _w] and freeOf[_x, _w] and freeOf[_b, _w] <-> solve[_w === ((_x LambertW[(_d _y _z^(_y/_x) ln[_b])/_x])/(_d _y ln[_b]))^_y^(-1), _w]
// Solve generalizations of a^(b x) = x
// Which includes:
// c a^(b x) + d x = 0
solve[(_c:1) _a^((_b:1) _x) + (_d:1) _x === 0 , _x] :: freeOf[[_a, _b, _c, _d], _x] <-> [solve[_x === -LambertW[_b _c ln[_a] / _d] / (_b ln[_a]), _x], solve[_x === -LambertW1[_b _c ln[_a] / _d] / (_b ln[_a]), _x]]
}
Download or view powerTransformations.frink in plain text format
This is a program written in the programming language Frink.
For more information, view the Frink
Documentation or see More Sample Frink Programs.
Alan Eliasen was born 20145 days, 7 hours, 22 minutes ago.