Related
According to the "Liqudity Math in uniswap v3", the liqudity of a position should be:
L = amt0 * (sqrt(upper) * sqrt(cprice)) / (sqrt(upper) - sqrt(cprice))
or
L = amt1 / (sqrt(cprice) - sqrt(lower))
I tried to calculate the liquidity of the below position on Arbitrum:
The nft token ID of the position is 69171, so I can get the liqudity by calling the contract(0xC36442b4a4522E871399CD717aBDD847Ab11FE88) on https://arbiscan.io
You can see it shows the liqudity is 50242219347523, and we can do more unit convertion:
Now I try to calcuate this number with the uniswap V3 math:
This is the output:
As we can see, the code output is very similar to the contract output, but if we look carefully, we will find the unit seems to be different. I know the unit of the contract ouput should be 'wei', but I don't know what the unit of the code results is. Can anybody help? Thanks.
I checked that position and pool. Best to query the current price from the pool's contract, for quick look the UI can be found at https://info.uniswap.org/#/arbitrum/pools/0x2f5e87c9312fa29aed5c179e456625d79015299c
The current price is shown as 11.9011 ETH per BTC, and there are 0.3122 BTC and 1.466 ETH in the pool. This gives:
price = 11.9011 * (1e18 / 1e8)
x = 0.3122 * 1e8
y = 1.466 * 1e18
The tick range of the position No. 69171 is 253300 to 259900. Use these values to calculate sp = sqrt(price) and the square roots of the price range boundaries, and from them, the liquidity:
sp = price ** 0.5
sa = 1.0001 ** (253300 // 2)
sb = 1.0001 ** (259900 // 2)
Lx = x * sp * sb / (sb - sp)
Ly = y / (sp - sa)
L = min(Lx, Ly)
The result Lx is 49905251975363.266 and Ly is 51071435112054.96. The Etherscan info shows liquidity L=50242219347523, in between these two values, which have a few % difference. A few % is an acceptable error given the imprecise input values used in this calculation; the UI shows the price and amount values in a rounded format.
I use a single function (that a create) to know if the character next to the current cursor position is a space
function Test_caractere_suivant_espace()
"Test si le caractère suivant est une espace"
let position = getcurpos()
let ligne = getline(position[1])
let car_suivant = ligne[position[2]]
if car_suivant == ' '
return 1
else
return 0
endfunction
It work well… but only with Ascii characters, not with not Ascii characters in UTF-8.
Of course, I could try the value of the two first bits of the current character, but is there anyway to have UTF-8 characters in the array returned by getline and not a list of one-byte values?
A pist of solution
DJMcMayhem suggest a solution using
let ligne = split(getline(position[1]), '\zs')
But there is still a problem to determine the next character.
Here is the new version of the function
function Test_caractere_suivant_espace()
"Test si le caractère suivant est une espace"
let position = getcurpos()
let ligne = split(getline(position[1]), '\zs')
let car_suivant = ligne[position[2]]
echom car_suivant
if car_suivant == ' '
return 1
else
return 0
endfunction
In this line
α α α α α α α α α α
If I call the function in the before last α, I get
Error detected while processing function LB_content[2]..Test_caractere_suivant_espace:
line 4:
E684: list index out of range: 25
E15: Invalid expression: ligne[position[2]]
line 5:
E121: Undefined variable: car_suivant
E15: Invalid expression: car_suivant
line 6:
E121: Undefined variable: car_suivant
E15: Invalid expression: car_suivant == ' '
Unfortunately, there's no way to do this that I am aware of. :h getline mentions nothing about encoding options, and from this vim mailing list I found, it seems like this problem has been around for a while with no fix.
However, I did figure out a hacky workaround. Instead of working with strings, you can work with a list of characters instead. Indexing into that will give you whole characters instead of individual bytes. Try this:
let ligne = split(getline(position[1]), '\zs')
Hello experienced pythoners.
The goal is simply to read in my own files which have the following format, and to then apply mathematical operations to these values and polynomials. The files have the following format:
m1:=10:
m2:=30:
Z1:=1:
Z2:=-1:
...
Some very similar variables, next come the laguerre polynomials
...
F:= (12.58295)*L(0,x)*L(1,y)*L(6,z) + (30.19372)*L(0,x)*L(2,y)*L(2,z) - ...:
Where L stands for a laguerre polynomial and takes two arguments.
I have written a procedure in Python which splits apart each line into a left and right hand side split using the "=" character as a divider. The format of these files is always the same, but the number of laguerre polynomials in F can vary.
import re
linestring = open("file.txt", "r").read()
linestring = re.sub("\n\n","\n",str(linestring))
linestring = re.sub(",\n",",",linestring)
linestring = re.sub("\\+\n","+",linestring)
linestring = re.sub(":=\n",":=",linestring)
linestring = re.sub(":\n","\n",linestring)
linestring = re.sub(":","",linestring)
LINES = linestring.split("\n")
for LINE in LINES:
LINE = re.sub(" ","",LINE)
print "LINE=", LINE
if len(LINE) <=0:
next
PAIR = LINE.split("=")
print "PAIR=", PAIR
LHS = PAIR[0]
RHS = PAIR[1]
print "LHS=", LHS
print "RHS=", RHS
The first re.sub block just deals with formatting the file and discarding characters that python will not be able to process; then a loop is performed to print 4 things, LINE, PAIR, LHS and RHS, and it does this nicely. using the example file from above the procedure will print the following:
LINE= m1=1
PAIR= ['m1', '1']
LHS= m1
RHS= 1
LINE= m2=1
PAIR= ['m2', '1']
LHS= m2
RHS= 1
LINE= Z1=-1
PAIR= ['Z1', '-1']
LHS= Z1
RHS= -1
LINE= Z2=-1
PAIR= ['Z2', '-1']
LHS= Z2
RHS= -1
LINE= F= 12.5*L(0,x)L(1,y) + 30*L(0,x)L(2,y)L(2,z)
PAIR=['F', '12.5*L(0,x)L(1,y) + 30*L(0,x)L(2,y)L(2,z)']
LHS= F
RHS= 12.5*L(0,x)L(1,y) + 30*L(0,x)L(2,y)L(2,z)
My question is what is the next best step to process this output and use it in a mathematical script, especially assigning the L to mean a laguerre polynomial? I tried putting the LHS and RHS into a dictionary, but found it troublesome to put F in it due to the laguerre polynomials.
Any ideas are welcome. Perhaps I am overcomplicating this and there is a much simpler way to parse this file.
Many thanks in advance
Your parsing algorithm doesn't seem to work correctly, as the RHS of your variables dont produce the expected result.
Also the first re.sub block where you want to format the file seems overly complicated. Assuming every statement in your input file is terminated by a colon, you could get rid of all whitespace and newlines and seperate the statements using the following code:
linestring = open('file.txt','r').read()
strippedstring = linestring.replace('\n','').replace(' ','')
statements = re.split(':(?!=)',strippedstring)[:-1]
Then you iterate over the statements and split each one in LHS and RHS:
for st in statements:
lhs,rhs = re.split(':=',st)
print 'lhs=',lhs
print 'rhs=',rhs
In the next step, try to distinguish normal float variables and polynomials:
#evaluate rhs
try:
#interpret as numeric constant
f = float(rhs)
print " ",f
except ValueError:
#interpret as laguerre-polynomial
summands = re.split('\+', re.sub('-','+-',rhs))
for s in summands:
m = re.match("^(?P<factor>-?[0-9]*(\.[0-9]*)?)(?P<poly>(\*?L\([0-9]+,[a-z]\))*)", s)
if not m:
print ' polynomial misformatted'
continue
f = m.group('factor')
print ' factor: ',f
p = m.group('poly')
for l in re.finditer("L\((?P<a>[0-9]+),(?P<b>[a-z])\)",p):
print ' poly: L(%s,%s)' % (l.group("a"),l.group("b"))
This should work for your given example file.
I need to convert GPS coordinates from WGS84 to decimal using Lua.
I am sure it's been done before, so I am looking for a hint to a code snippet.
corrected question: Code to convert DMS (Degress Minutes Seconds) to DEG ((decimal) Degrees) in Lua?
examples:
Vienna: dms: 48°12'30" N 16°22'28" E
or
Zurich: dms: 47°21'7" N 8°30'37" E
The difficulty I find is to get the numbers out of these strings.
Especially how to handle the signs for degree (°) minutes (') and seconds (").
So that I would have for example a table coord{} per coordinate to deal with.
coord {1} [48]
coord {2} [12]
coord {3} [30]
coord {4} [N]
coord {5} [16]
coord {6} [22]
coord {7} [28]
coord {8} [E]
Suggestions are appreciated, thanks.
Parse the string latlon = '48°12'30" N 16°22'28" E' into DMS+heading components:
This is your string (note the escaped single-quote):
latlon = '48°12\'30" N 16°22\'28" E'
Break it down into two steps: the lat/lon, then components of each. You need captures "()", ignore spaces around the heading (N and E) with "%s*":
lat, ns, lon, ew = string.match(latlon, '(.*)%s*(%a)%s*(.*)%s*(%a)')
The lat is now 48°12'30", ns is 'N', lon is 16°22'28", ew is 'E'. For components of lat, step by step:
-- string.match(lat, '48°12'30"') -- oops the ' needs escaping or us
-- string.match(lat, '48°12\'30"')
-- ready for the captures:
-- string.match(lat, '(48)°(12)\'(30)"') -- ready for generic numbers
d1, m1, s1 = string.match(lat, '(%d+)°(%d+)\'(%d+)"')
d2, m2, s2 = string.match(lon, '(%d+)°(%d+)\'(%d+)"')
Now that you know (d1, m1, s1, ns) and (d2, m2, s2, ew), you have:
sign = 1
if ns=='S' then sign = -1 end
decDeg1 = sign*(d1 + m1/60 + s1/3600)
sign = 1
if ew=='W' then sign = -1 end
decDeg2 = sign*(d2 + m2/60 + s2/3600)
For your values of lat, you get decDeg1 = 48.208333 which is the correct value according to online calculators (like http://www.satsig.net/degrees-minutes-seconds-calculator.htm).
Write a Prolog program to print out a square of n*n given characters on the screen. Call your predicate square/2. The first argument should be a (positive) integer. the second argument the character (any Prolog term) to be printed. Example:
?-square(5, '*').
*****
*****
*****
*****
*****
Yes
I just start to learn this language. I did this:
square(_,'_').
square(N, 'B') :-
N>0,
write(N*'B').
It doesn't work at all. Can anyone help me?
So your question is, basically, "how do I write a loop nested in a loop?"
This is how you write an empty loop with an integer for a counter:
loop(0).
loop(N) :- N > 0, N0 is N-1, loop(N0).
which in C would be:
for(i=0; i < n; ++i) { }
And you seem to know already how to print (write(foo)).
Decompose the problem. To write an NxN square, you need to do two things:
Write N lines
Write a single line, consisting of N characters followed by a newline character.
The second is easy:
do_line(0,_) :-
nl
.
do_line(N,C) :-
N > 0 ,
write(C) ,
N1 is N-1 ,
do_line(N1,C)
.
The first isn't much more difficult:
do_lines(0,_,_).
do_lines(M,N,C) :-
M > 0 ,
do_line(N,C) ,
M1 is M-1 ,
do_lines(M1,N,C)
.
The all you need to do is wrap it:
write_square(N,C) :- do_lines(N,N,C) .
Easy!
You need to draw a line of N stars/characters
line(N,X):- N>0, N1 is N-1, line(N1,X), write(X), fail; true.
Then you will draw a column of N lines of stars/characters.
s(N,Chr):-sAux(N,0,Chr).
sAux(N,N,Chr).
sAux(N,C,Chr):-C<N, C1 is C+1, sAux(N, C1, Chr), line(N,Chr),nl.
s(N,Chr):- N>0, N1 is N-1, s(N1,X), linie(N,X), nl, fail;true.
Doing this:
square2(0,_). % base case, recursion stops when X reaches 0, second argument is irrelevent
square2(X,Symbol):-
X1 is X - 1,
write(Symbol),
square2(X1,Symbol).
With the query, which results in:
?- square2(5,'* ').
* * * * *
Therefore, we need another loop to make it write X times.
square1(0,_,_). % base case, recursion stops when X reaches 0
square1(X,Y,Symbol):-
X1 is X - 1,
square2(Y,Symbol), % with the same Y passed in square2 predicate to print a line of symbols
nl, % creates a new line
square1(X1,Y,Symbol).
However, the question is asking for the format with square(5, '* '). Therefore,
square(X,Symbol):-
square1(X,X,Symbol).
To wrap up:
square(X,Symbol):-
square1(X,X,Symbol).
square1(0,_,_).
square1(X,Y,Symbol):-
X1 is X - 1,
square2(Y,Symbol),
nl,
square1(X1,Y,Symbol).
square2(0,_).
square2(X,Symbol):-
X1 is X - 1,
write(Symbol),
square2(X1,Symbol).