Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Missing context : This is a tertiary question following my answer to this question ; I already answered shis tertiary question in a comment that seems to have escaped the OP's attention. I'll repeat with amplification :

Here :

sage: Sys0
[A*K^(beta - 1)*L^alpha*beta*p == r, A*K^beta*L^(alpha - 1)*alpha*p == w]

One wants to solve this system for L and K. None of the solvers included in Sage can solve this system :

sage: solve(Sys0, [L, K])
[A*K^beta*L^(alpha - 1)*alpha*p == w, A*K^(beta - 1)*L^alpha*beta*p == r]
sage: solve(Sys0, [L, K], to_poly_solve=True)
[A*K^beta*L^(alpha - 1)*alpha*p == w, A*K^(beta - 1)*L^alpha*beta*p == r]
sage: solve(Sys0, [L, K], algorithm="giac")
Warning, the test a==b is performed by checking
that the internal representation of regroup(a-b) is not 0.
Therefore a==b may return false even if a and b are mathematically equal,
if they have different internal representations.
You can explicitly call a simplification function like simplify(a-b)==0 to avoid this.
[[L, K]]
sage: solve(Sys0, [L, K], algorithm="fricas")
[A*K^beta*L^(alpha - 1)*alpha*p == w, A*K^(beta - 1)*L^alpha*beta*p == r]
sage: solve(Sys0, [L, K], algorithm="sympy")
---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
Cell In [26], line 1
----> 1 solve(Sys0, [L, K], algorithm="sympy")

File /usr/local/sage-10/src/sage/symbolic/relation.py:1106, in solve(f, *args, **kwds)
   1104     sympy_vars = tuple([v._sympy_() for v in x])
   1105 if len(sympy_vars) > 1 or not isinstance(f, Expression):
-> 1106     ret = ssolve(sympy_f, sympy_vars, dict=True)
   1107     if isinstance(ret, dict):
   1108         if solution_dict:

File /usr/local/sage-10/local/var/lib/sage/venv-python3.11/lib/python3.11/site-packages/sympy/solvers/solvers.py:1147, in solve(f, *symbols, **flags)
   1145         solution = _solve(f[0], *symbols, **flags)
   1146 else:
-> 1147     linear, solution = _solve_system(f, symbols, **flags)
   1148 assert type(solution) is list
   1149 assert not solution or type(solution[0]) is dict, solution

File /usr/local/sage-10/local/var/lib/sage/venv-python3.11/lib/python3.11/site-packages/sympy/solvers/solvers.py:1962, in _solve_system(exprs, symbols, **flags)
   1960         got_s.add(s)
   1961     if not hit:
-> 1962         raise NotImplementedError('could not solve %s' % eq2)
   1963 else:
   1964     result = newresult

NotImplementedError: could not solve A*L**alpha*beta*p*((L**(1 - alpha)*w/(A*alpha*p))**(1/beta))**(beta - 1) - r

The point is that both equations include an exponential, which we'll eliminate by taking the logarithm of each side. This could be done manually :

sage: [Sys0[0].lhs().log().log_expand()==Sys0[0].rhs().log().log_expand(), Sys0[1].lhs().log().log_expand()==Sys0[1].rhs().log().log_expand()]
[(beta - 1)*log(K) + alpha*log(L) + log(A) + log(beta) + log(p) == log(r),
 beta*log(K) + (alpha - 1)*log(L) + log(A) + log(alpha) + log(p) == log(w)]

[ This is now a linear system in |log(K)andlog(L)`, which can be easily solved by Sage (at the price of substituting new variables to these expressions...) and backsubstituting in the solutions. See my answer to the previous question. ]

A first way of being lazy is ti apply a similar transformation to each element of the system, by using list building by enumeration, a common Pythonyism :

sage: [u.lhs().log().log_expand()==u.rhs().log().log_expand() for u in Sys0]
[(beta - 1)*log(K) + alpha*log(L) + log(A) + log(beta) + log(p) == log(r),
 beta*log(K) + (alpha - 1)*log(L) + log(A) + log(alpha) + log(p) == log(w)]

A second way to be lazy is to remark that an equation is represented in Python by the application of the eq operator :

sage: Sys0[0].operator()
<built-in function eq>

to two arguments (its left and right sides)

sage: Sys0[0].operands()
[A*K^(beta - 1)*L^alpha*beta*p, r]

There, another common Pythonism is to apply the operator to the list of its arguments. Symbolically :

$$ f(x,y)=f(*[x, y]) $$

, as noted by Max Alexeyev... Hence the lazier representation of the opration "take the logs pf each side ofeach equation" is represented by :

sage: [u.operator()(*[v.log().log_expand() for v  in u.operands()]) for u in Sys0]
[(beta - 1)*log(K) + alpha*log(L) + log(A) + log(beta) + log(p) == log(r),
 beta*log(K) + (alpha - 1)*log(L) + log(A) + log(alpha) + log(p) == log(w)]

Being terminally lazy, a third abbreviation of this expression is to replace the inner list enumeration by the mapping of an (anonymous) ad hoc function to the operands :

sage: [u.operator()(*map(lambda u:u.log().log_expand(), u.operands())) for u in Sys0]
[(beta - 1)*log(K) + alpha*log(L) + log(A) + log(beta) + log(p) == log(r),
 beta*log(K) + (alpha - 1)*log(L) + log(A) + log(alpha) + log(p) == log(w)]

One can note that iterating the same replacement to the outer loop (on the system's elements) would result in returning a map object rather than a list. All Sage solvers do not accept such an argument...

I hope this is now clear...

I finally note that Mathematica doesn't need such handholding and solves the original system :

sage: [[es[1].sage()==es[2].sage() for es in s] for s in mathematica.Solve(Sys0, [L, K])]
[[L == e^((beta*log(alpha) - beta*log(beta) + beta*log(r) - beta*log(w) - log(A) - log(alpha) - log(p) + log(w))/(alpha + beta - 1)),
  K == e^(-(alpha*log(alpha) - alpha*log(beta) + alpha*log(r) - alpha*log(w) + log(A) + log(beta) + log(p) - log(r))/(alpha + beta - 1))]]