Ask Your Question
0

Just a little help to decifer a command

asked 2023-10-30 21:49:18 +0200

Cyrille gravatar image

I need some help to decifer the following command

[u.operator()(*map(lambda v:v.log().log_expand(), u.operands())) for u in Sys0]

The problem is not the following part (*map(lambda v:v.log().log_expand(), u.operands())) I know that * unpack the u.operands() and I know lambda functions. But I find nothing in the docs on operator (there is a documentation on operators but I find nothing on operator). Then what troubles me is the syntax u.operator()().

By advance thanks for the explanation.

edit retag flag offensive close merge delete

Comments

Please provide more context: what sorts of object is u? My guess is this: https://doc.sagemath.org/html/en/refe..., in which case u.operator() returns an operator, like addition, and u.operator()(args) would then add the arguments.

John Palmieri gravatar imageJohn Palmieri ( 2023-10-30 22:38:35 +0200 )edit

Wouldn't it be the same as simply u(args)?

Max Alekseyev gravatar imageMax Alekseyev ( 2023-10-30 23:03:39 +0200 )edit

1 Answer

Sort by ยป oldest newest most voted
1

answered 2023-10-31 09:19:00 +0200

Emmanuel Charpentier gravatar image

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))]]
edit flag offensive delete link more

Comments

Thanks Emmanuel. I haved understood your code for my previous question up to the fact that you have writen u.operator()( something). I have the habit to write something like u.operator() but the second parenthesis, ( something) is new for me. For the rest all was understandable. Even in reading Python and SageMath documentation, when one doesn't know where to search the syntax is sometime difficult dot understand.

Cyrille gravatar imageCyrille ( 2023-10-31 21:00:13 +0200 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2023-10-30 21:49:18 +0200

Seen: 74 times

Last updated: Oct 31 '23