I need the Lua math library in NodeMCU - algorithm

I need to perform log calculations for a thermistor, however the Lua math library (math.log) doesn't seem to be implemented, or I'm doing something wrong. It's not a module on NodeMCU-build.com or in the docs, either.
Any ideas/suggestions/solutions?

local function log(x)
assert(x > 0)
local a, b, c, d, e, f = x < 1 and x or 1/x, 0, 0, 1, 1
repeat
repeat
c, d, e, f = c + d, b * d / e, e + 1, c
until c == f
b, c, d, e, f = b + 1 - a * c, 0, 1, 1, b
until b <= f
return a == x and -f or f
end
local function log10(x)
return log(x) / 2.3025850929940459
end

Related

Mathematica Code with Module and If statement

Can I simply ask the logical flow of the below Mathematica code? What are the variables arg and abs doing? I have been searching for answers online and used ToMatlab but still cannot get the answer. Thank you.
Code:
PositiveCubicRoot[p_, q_, r_] :=
Module[{po3 = p/3, a, b, det, abs, arg},
b = ( po3^3 - po3 q/2 + r/2);
a = (-po3^2 + q/3);
det = a^3 + b^2;
If[det >= 0,
det = Power[Sqrt[det] - b, 1/3];
-po3 - a/det + det
,
(* evaluate real part, imaginary parts cancel anyway *)
abs = Sqrt[-a^3];
arg = ArcCos[-b/abs];
abs = Power[abs, 1/3];
abs = (abs - a/abs);
arg = -po3 + abs*Cos[arg/3]
]
]
abs and arg are being reused multiple times in the algorithm.
In a case where det > 0 the steps are
po3 = p/3;
b = (po3^3 - po3 q/2 + r/2);
a = (-po3^2 + q/3);
abs1 = Sqrt[-a^3];
arg1 = ArcCos[-b/abs1];
abs2 = Power[abs1, 1/3];
abs3 = (abs2 - a/abs2);
arg2 = -po3 + abs3*Cos[arg1/3]
abs3 can be identified as A in this answer: Using trig identity to a solve cubic equation
That is the most salient point of this answer.
Evaluating symbolically and numerically may provide some other insights.
Using demo inputs
{p, q, r} = {-2.52111798, -71.424692, -129.51520};
Copyable version of trig identity notes - NB a, b, p & q are used differently in this post
Plot[x^3 - 2.52111798 x^2 - 71.424692 x - 129.51520, {x, 0, 15}]
a = 1;
b = -2.52111798;
c = -71.424692;
d = -129.51520;
p = (3 a c - b^2)/3 a^2;
q = (2 b^3 - 9 a b c + 27 a^2 d)/27 a^3;
A = 2 Sqrt[-p/3]
A == abs3
-(b/3) + A Cos[1/3 ArcCos[
-((b/3)^3 - (b/3) c/2 + d/2)/Sqrt[-(-(b^2/9) + c/3)^3]]]
Edit
There is also a solution shown here
TRIGONOMETRIC SOLUTION TO THE CUBIC EQUATION, by Alvaro H. Salas
Clear[a, b, c]
1/3 (-a + 2 Sqrt[a^2 - 3 b] Cos[1/3 ArcCos[
(-2 a^3 + 9 a b - 27 c)/(2 (a^2 - 3 b)^(3/2))]]) /.
{a -> -2.52111798, b -> -71.424692, c -> -129.51520}
10.499

Solving a simple geometric puzzle in CLPQ/R (Prolog)

Consider the following square:
You are given three constraints:
All rectangles (A, B, C, D and E) have the same area;
Their geometric layout constitutes a square; and
The height of A is 2.
Now, I know this is very simple to solve by hand, but I thought it would be a very good example to show off the capabilities of CLP(Q/R) with Prolog:
SPOILER ALERT: If you want to first solve the puzzle by yourself, do not continue to read this, as there are constraints that will give away the solution.
Anyway, here's my attempt at defining (with I think include redundant constraints) this puzzle with CLP(Q/R):
:- use_module(library(clpr)).
solve(Eh) :-
A = B, B = C, C = D, D = E,
{ A >= 1, B >= 1, C >= 1, D >= 1, E >= 1,
Aw >= 1, Bw >= 1, Cw >= 1, Dw >= 1, Ew >= 1 },
{ Ah = 2 },
{ A = Ah * Aw,
B = Bh * Bw,
C = Ch * Cw,
D = Dh * Dw,
E = Eh * Ew },
{ (Bw + Cw) = Aw,
Dw = Cw,
(Ah + Bh) = Eh,
(Ch + Dh) = Bh,
(Aw + Ew) = Eh },
minimize(Eh).
Which when queried:
?- solve(Eh).
false.
...makes me sad. Such a beautiful example for a constraint solver... Anyone cares to undo my sadness?
Addendum: I used Mathematica and the FindMinimum function to check for my constraints. It seems to be working:
domain = a >= 1 && b >= 1 && c >= 1 && d >= 1 && e >= 1 && ah == 2.0 && a == b == c == d == e && aw >= 1 && bw >= 1 && cw >= 1 && dw >= 1 && ew >= 1
rectangles = (a == ah*aw && b == bh*bw && c == ch*cw && d == dh*dw && e == eh*ew)
FindMinimum[{eh,
domain && rectangles &&
((bw + cw ) == aw && dw == cw && (ah + bh) == eh && (ch + dh) == bh && (aw + ew) == eh)},
{a, b, c, d, e, ah, aw, bh, bw, ch, cw, dh, dw, eh, ew}]
Answers:
{8., {a -> 12.8, b -> 12.8, c -> 12.8, d -> 12.8, e -> 12.8,
ah -> 2., aw -> 6.4, bh -> 6., bw -> 2.13333, ch -> 3.,
cw -> 4.26667, dh -> 3., dw -> 4.26667,
eh -> 8., ew -> 1.6}}
There is a old/new entry in CLP, clpBNR. You can install it in a recent version of SWI-Prolog.
I think it would require to group equations together into a single {}.
?- pack_install(clpBNR).
:- use_module(library(clpBNR)).
solve_(Eh) :-
Vs = [A,B,C,D,E, Aw,Bw,Cw,Dw,Ew, Ah,Bh,Ch,Dh,Eh],
Vs::real(1,100),
{ Ah == 2,
A is Ah * Aw,
B is Bh * Bw,
C is Ch * Cw,
D is Dh * Dw,
E is Eh * Ew,
A == B,
B == C,
C == D,
D == E,
(Bw + Cw) == Aw,
Dw == Cw,
(Ah + Bh) == Eh,
(Ch + Dh) == Bh,
(Aw + Ew) == Eh
},
solve(Vs).
?- solve_(Eh).
::(Eh, ...( 8.000000)) .

How to recover an image from another given image

If I have a grey-scale, square image (1) and I rotate a copy of it by 90 degrees. I create a new image (2) where the pixels are the sum of the original and rotated images. My question is if I only have image 2 how can I recover the original image 1?
The short answer is: you can't recover the original image.
Proof:
Assume 2x2 image:
I = [a b]
[c d]
J = I + rot90(I) = [ a + b, b + d] = [E F
[ a + c, c + d] G H]
Now lets try to solve the linear equation system:
E = a + b + 0 + 0
F = 0 + b + 0 + d
G = a + 0 + c + 0
H = 0 + 0 + c + d
A = [a, b, 0, 0 u = [a v = [E
0, b, 0, d b F
a, 0, c, 0 c G
0, 0, c, d] d] H]
v = A*u
In order to extract u, matrix A must be invertibale.
but det(A) = 0, so there are infinite possible solutions.
I tried an iterative approach.
I implemented it in MATLAB.
I played with it a little, and found out that applying bilateral filter, and moderated sharpening, improves the reconstructed result.
There are probably better heuristics, that I can't think off.
Here is the MATLAB implementation:
I = im2double(imread('cameraman.tif'))/2; %Read input sample image and convert to double
J = I + rot90(I); %Sum of I and rotated I.
%Initial guess.
I = ones(size(J))*0.5;
h_fig = figure;
ax = axes(h_fig);
h = imshow(I/2);
alpha = 0.1;
beta = 0.01;
%100000 iterations.
for i = 1:100000
K = I + rot90(I);
E = J - K; %E is the error matrix.
I = I + alpha*E;
if mod(i, 100) == 0
if (i < 100000*0.9)
I = imsharpen(imbilatfilt(I), 'Amount', 0.1);
end
h.CData = I*2;
ax.Title.String = num2str(i);
pause(0.01);
beta = beta * 0.99;
end
end
Sum of I and rot90(I):
Original image:
Reconstructed image:

Prolog singleton variable in branch

I have the below code:
loc_sucs(R, C, result(A, S)) :-
loc_sucs(R, C, S),
Rm is R - 1,
A \= move-north;
R = 0;
o(Rm, C);
r(Rm, C, S);
Rp is R + 1,
dim(Z, _),
A \= move-south;
R = Z;
o(Rp, C);
r(Rp, C, S);
Cp is C + 1,
dim(_, W),
A \= move-east;
C = W;
o(R, Cp);
r(R, Cp, S);
Cm is C - 1,
A \= move-west;
C = 0;
o(R, Cm);
r(R, Cm, S).
And I'm getting the singleton warning for Rm, Cm, Rp, Cp, Z and W. Why am I getting this warning if all of these variables are used more than once?

Unwanted evaluation on prolog

I was making a prolog knowledge base to implement geometry rules. When testing if a rectangle had a right angle, I found two answers.
?- rect_tri(triangle(line(point(0,0),point(0,1)),line(point(0,1),point(1,0)),line(point(1,0),point(0,0)))).
true ;
false.
Here is the kwnoledge base:
point(X,Y).
line(X,Y) :- X = point(A,B), Y = point(C,D), not(X = Y).
len(X,R) :- X = line(P,Q), P = point(A,B), Q = point(C,D), not(P = Q),
R is sqrt((A - C) * (A - C) + (B - D) * (B - D)).
triangle(X,Y,Z) :- X = point(A,B), Y = point(C,D), Z = point(E,F),
not(X = Y), not(X = Z), not(Y = Z),
L1 = line(X,Y), L2 = line(X,Z), L3 = line(Y,Z),
len(L1,G), len(L2,H), len(L3,I),
G + H > I, G + I > H, H + I > G.
triangle(X,Y,Z) :- X = line(A,B), Y = line(B,C), line(A,C),
len(X,G), len(Y,H), len(Z,I),
G + H > I, G + I > H, H + I > G.
rect_tri(X) :- X = triangle(A,B,C), len(A,G), len(B,H), len(C,I),
(G is sqrt(H * H + I * I);
H is sqrt(G * G + I * I);
I is sqrt(H * H + G * G)).
When tracing, I found that the answer true comes when prolog hits the line H is sqrt(G * G + I * I), and false when it evaluates the last line.
I don't want the last evaluation to occur, because I want it to exit when a true has been found.
Daniel comment probably shows the most sensible way to solve your problem. Some other option...
in modern compilers there is the if/then/else construct:
rect_tri(X) :- X = triangle(A,B,C), len(A,G), len(B,H), len(C,I),
( G is sqrt(H * H + I * I)
-> true
; H is sqrt(G * G + I * I)
-> true
; I is sqrt(H * H + G * G)
).
You could as well use cuts (old fashioned way, somewhat more readable here):
rect_tri(X) :- X = triangle(A,B,C), len(A,G), len(B,H), len(C,I),
( G is sqrt(H * H + I * I), !
; H is sqrt(G * G + I * I), !
; I is sqrt(H * H + G * G)
).

Resources