Related
I am trying to find a common tangent to two curves using python but I am not able to solve it.
The equations to the two curves are complicated that involve logarithms.
Is there a way in python to compute the x coordinates of a tangent that is common to both the curves in general. If I have 2 curves f(x) and g(x), I want to find the x-coordinates x1 and x2 on a common tangent where x1 lies on f(x) and x2 on g(x). I am trying f'(x1) = g'(x2) and f'(x1) = f(x1) - f(x2) / (x1 - x2) to get x1 and x2 but I am not able to get values using nonlinsolve as the equations are too complicated.
I want to just find x-coordinates of the common tangent
Can anyone suggest a better way?
import numpy as np
import sympy
from sympy import *
from matplotlib import pyplot as plt
x = symbols('x')
a, b, c, d, e, f = -99322.50019502985, -86864.87072433547, -96876.05627516498, -89703.35055202093, -3390.863799999999, -20942.518
def func(x):
y1_1 = a - a*x + b*x
y1_2 = c - c*x + d*x
c1 = (1 - x) ** (1 - x)
c2 = (x ** x)
y2 = 12471 * (sympy.log((c1*c2)))
y3 = 2*f*x**3 - x**2*(e + 3*f) + x*(e + f)
eqn1 = y1_1 + y2 + y3
eqn2 = y1_2 + y2 + y3
return eqn1, eqn2
val = np.linspace(0, 1)
f1 = sympy.lambdify(x, func(x)[0])(val)
f2 = sympy.lambdify(x, func(x)[1])(val)
plt.plot(val, f1)
plt.plot(val, f2)
plt.show()
I am trying this
x1, x2 = sympy.symbols('x1 x2')
fun1 = func(x1)[0]
fun2 = func(x2)[0]
diff1 = diff(fun1,x1)
diff2 = diff(fun2,x2)
eq1 = diff1 - diff2
eq2 = diff1 - ((fun1 - fun2) / (x1 - x2))
sol = nonlinsolve([eq1, eq2], [x1, x2])
the first thing that needs to be done is to reduce the formulas
for example the first formula is actually this:
formula = x*(1 - x)*(17551.6542 - 41885.036*x) + x*(1 - x)*(41885.036*x - 24333.3818) + 12457.6294706944*x + log((x/(1 - x))**(12000*x)*(1 - x)**12000) - 99322.5001950298
formula = (x-x^2)*(17551.6542 - 41885.036*x) + (x-x^2)*(41885.036*x - 24333.3818) + 12457.6294706944*x + log((x/(1 - x))**(12000*x)*(1 - x)**12000) - 99322.5001950298
# constants
a = 41885.036
b = 17551.6542
c = 24333.3818
d = 12457.6294706944
e = 99322.5001950298
f = 12000
formula = (x-x^2)*(b - a*x) + (x-x^2)*(a*x - c) + d*x + log((x/(1 - x))**(f*x)*(1 - x)**f) - e
formula = (ax^3 -bx^2 + bx - ax^2) + (x-x^2)*(a*x - c) + d*x + log((x/(1 - x))**(f*x)*(1 - x)**f) - e
formula = ax^3 -bx^2 + bx - ax^2 -ax^3 + ax^2 + cx^2 -cx + d*x + log((x/(1 - x))**(f*x)*(1 - x)**f) - e
# collect x terms by power (note how the x^3 tern drops out, so its easier).
formula = (c-b)*x^2 + (b-c+d)*x + log((x/(1 - x))**(f*x)*(1 - x)**f) - e
which is much cleaner and is a quadratic with a log term.
i expect that you can do some work on the log term too, but this is an excercise for the original poster.
likewise the second formula can be reduced in the same way, which is again an excercise for the original poster.
From this, both equations need to be differentiated with respect to x to find the tangent. Then set both formulas to be equal to each other (for a common tangent).
This would completely solve the question.
I actually wonder if this is a python question at all or actually a pure maths question.....
The important point to note is that, since the derivatives are monotonic, for any value of derivative of fun1, there is a solution for fun2. This can be easily seen if you plot both derivatives.
Thus, we want a function that, given an x1, returns an x2 that matches it. I'll use numerical solution because the system is too cumbersome for numerical solution.
import scipy.optimize
def find_equal_value(f1, f2, x, x1):
goal = f1.subs(x, x1)
to_solve = sympy.lambdify(x, (f2 - goal)**2) # Quadratic functions tend to be better behaved, and the result is the same
sol = scipy.optimize.fmin(func=to_solve, x0=x1, ftol=1e-8, disp=False) # The value for f1 is a good starting guess
return sol[0]
I used fmin as the solver above because it worked and I knew how to use it by heart. Maybe root_scalar can give better results.
Using the function above, let's get some pairs (x1, x2) where the derivatives are equal:
df1 = sympy.diff(func(x)[0])
df2 = sympy.diff(func(x)[1])
x1 = 0.25236537 # Close to the zero derivative
x2 = find_equal_value(df1, df2, x, x1)
print(f'Derivative of f1 in x1: {df1.subs(x, x1)}')
print(f'Derivative of f2 in x2: {df2.subs(x, x2)}')
print(f'Error: {df1.subs(x, x1) - df2.subs(x, x2)}')
This results is:
Derivative of f1 in x1: 0.0000768765858083498
Derivative of f2 in x2: 0.0000681969431752805
Error: 0.00000867964263306931
If you want a x2 for several x1s (beware that in some cases the solver hits a value where the logs are invalid. Always check your result for validity):
x1s = np.linspace(0.2, 0.8, 50)
x2s = [find_equal_value(df1, df2, x, x1) for x1 in x1s]
plt.plot(x1s, x2s); plt.grid(); plt.show()
I think it’s the easiest way to describe my problem with a small example.
I have this data which is my input data. I have 3 LEDs and each LED is represented by 4 color-parts (value 1 to 4 in each array). If I increase the intensity of the LEDs (in this example from 10% to 30%) the color-parts change in different ways.
LED1_10 = np.array([1.5, 1, 0.5, 0.5])
LED1_20 = np.array([2.5, 1.75, 1.2, 1.2])
LED1_30 = np.array([3, 2.3, 1.7, 1.7])
LED2_10 = np.array([0.2, 0.8, 0.4, 0.4])
LED2_20 = np.array([0.6, 1.6, 0.5, 0.5])
LED2_30 = np.array([1.0, 2.0, 0.55, 0.55])
LED3_10 = np.array([1, 0.1, 0.4, 0.4])
LED3_20 = np.array([2.5, 0.8, 0.9, 0.9])
LED3_30 = np.array([3.25, 1, 1.3, 1.3])
The column elements of the arrays belong together. So if I bring LED1 from 10% to 30% the value in column 1 rises from 1.5 to 2.5 and then to 3. I want to find a polynomial for the rise of each of the LED color-parts, so I rearrange the data and use a polynomial fit to get the equations which describe the way the values are rising for each LED.
### Rearrange the values
LED1 = np.stack((LED1_10, LED1_20, LED1_30)).T
LED2 = np.stack((LED2_10, LED2_20, LED2_30)).T
LED3 = np.stack((LED3_10, LED3_20, LED3_30)).T
### Create x-vectro
x = np.array([10,20,30])
### Polynomal fits
Fit_LED1 = []
for i in range(len(LED1)):
z = np.polyfit(x, LED1[i], 2)
Fit_LED1.append(z)
Fit_LED2 = []
for i in range(len(LED2)):
z = np.polyfit(x, LED2[i], 2)
Fit_LED2.append(z)
Fit_LED3 = []
for i in range(len(LED3)):
z = np.polyfit(x, LED3[i], 2)
Fit_LED3.append(z)
Now I want to generate light of a specific color mixing together the light of each of the 3 different LEDs. Therefor I need to find out which intensity I need to use from each of the LEDs to get the best possible result. Color-parts 1-4 are represented by the solution vector: b = [7, 8, 2, 5] I do this solving the overdetermined nonlinear equation system like this:
def f(x):
x1, x2, x3 = x
return np.asarray(((-2.50000000e-03*x1**2 + 1.75000000e-01*x1 + -5.91091254e-15) + (-2.03207837e-18*x2**2 + 4.00000000e-02*x2 + -2.00000000e-01) + (-0.00375*x3**2 + 0.2625*x3 + -1.25),
(-0.001*x1**2 + 0.105*x1 + 0.05) + (-0.002*x2**2 + 0.14*x2 + -0.4) + (-0.0025*x3**2 + 0.145*x3 + -1.1),
(-0.001*x1**2 + 0.1*x1 + -0.4 ) + (-0.00025*x2**2 + 0.0175*x2 + 0.25) + (-0.0005*x3**2 + 0.065*x3 + -0.2),
(-0.001*x1**2 + 0.1*x1 + -0.4 ) + (-0.00025*x2**2 + 0.0175*x2 + 0.25) + (-0.0005*x3**2 + 0.065*x3 + -0.2)))
def system(x,b):
return (f(x)-b)
b = [7, 8, 2, 5]
x = scipy.optimize.leastsq(system, np.asarray((1,1,1)), args=b)[0]
I used the polynomials I got from the fit for each LED and added them to each other to get a equation for each of the four color parts. This would give the same result and maybe is a bit easier to read:
def g(x):
x1, x2, x3 = x
return np.asarray(((Fit_LED1[0][0]*x1**2 + Fit_LED1[0][1]*x1 + Fit_LED1[0][2]) + (Fit_LED2[0][0]*x1**2 + Fit_LED2[0][1]*x1 + Fit_LED2[0][2]) + (Fit_LED3[0][0]*x1**2 + Fit_LED3[0][1]*x1 + Fit_LED3[0][2]),
(Fit_LED1[1][0]*x1**2 + Fit_LED1[1][1]*x1 + Fit_LED1[1][2]) + (Fit_LED2[1][0]*x1**2 + Fit_LED2[1][1]*x1 + Fit_LED2[1][2]) + (Fit_LED3[1][0]*x1**2 + Fit_LED3[1][1]*x1 + Fit_LED3[1][2]),
(Fit_LED1[2][0]*x1**2 + Fit_LED1[2][1]*x1 + Fit_LED1[2][2]) + (Fit_LED2[2][0]*x1**2 + Fit_LED2[2][1]*x1 + Fit_LED2[2][2]) + (Fit_LED3[2][0]*x1**2 + Fit_LED3[2][1]*x1 + Fit_LED3[2][2]),
(Fit_LED1[3][0]*x1**2 + Fit_LED1[3][1]*x1 + Fit_LED1[3][2]) + (Fit_LED2[3][0]*x1**2 + Fit_LED2[3][1]*x1 + Fit_LED2[3][2]) + (Fit_LED3[3][0]*x1**2 + Fit_LED3[3][1]*x1 + Fit_LED3[3][2])))
def system(x,b):
return (f(x)-b)
b = [5, 8, 4, 12]
x = scipy.optimize.leastsq(system, np.asarray((1,1,1)), args=b)[0]
Now my problem is that I need to type each of the functions separately which is a lot of work, especially because my real-world application consists of 40 LEDs and more than 1000 color-parts for each of the LEDs. Is there an easier and more efficient way to define the equations for the equations system rather than typing each of the separately like I did here?
def g(x):
x1, x2, x3 = x
return np.asarray(((Fit_LED1[0][0]*x1**2 + Fit_LED1[0][1]*x1 + Fit_LED1[0][2]) + (Fit_LED2[0][0]*x1**2 + Fit_LED2[0][1]*x1 + Fit_LED2[0][2]) + (Fit_LED3[0][0]*x1**2 + Fit_LED3[0][1]*x1 + Fit_LED3[0][2]),
(Fit_LED1[1][0]*x1**2 + Fit_LED1[1][1]*x1 + Fit_LED1[1][2]) + (Fit_LED2[1][0]*x1**2 + Fit_LED2[1][1]*x1 + Fit_LED2[1][2]) + (Fit_LED3[1][0]*x1**2 + Fit_LED3[1][1]*x1 + Fit_LED3[1][2]),
(Fit_LED1[2][0]*x1**2 + Fit_LED1[2][1]*x1 + Fit_LED1[2][2]) + (Fit_LED2[2][0]*x1**2 + Fit_LED2[2][1]*x1 + Fit_LED2[2][2]) + (Fit_LED3[2][0]*x1**2 + Fit_LED3[2][1]*x1 + Fit_LED3[2][2]),
(Fit_LED1[3][0]*x1**2 + Fit_LED1[3][1]*x1 + Fit_LED1[3][2]) + (Fit_LED2[3][0]*x1**2 + Fit_LED2[3][1]*x1 + Fit_LED2[3][2]) + (Fit_LED3[3][0]*x1**2 + Fit_LED3[3][1]*x1 + Fit_LED3[3][2])))
I hope I was able to make my problem clear and would be very thankful if anyone could help me solving this task.
Thank you very much in advance :)
There is a pattern in your equations which you can vectorise. First of all, gather all the LED fits in a 3D array.
fits = np.array([Fit_LED1, Fit_LED2, Fit_LED3])
And then define g(x) as
def g(x):
X = np.array([x**2, x, np.ones_like(x)]).T
return np.sum(fits * X[:,None], axis=(0, 2))
You can also confirm the result is correct with np.isclose(f(x), g(x)).
Of course you should do the same to LED1, LED2, etc so you don't have to hardcode Fit_LED1, etc. Just put everything in a 3d array and loop for each LED index.
LEDs = np.array([LED1, LED2, LED3])
fits = [
[np.polyfit(np.array([10, 20, 30]), LEDs[i,j], 2) for j in range(LEDs.shape[1])]
for i in range(LEDs.shape[0])
]
fits = np.array(fits)
I took a cryptography course this semester in graduate school, and once of the topics we covered was NTRU. I am trying to code this in pure Python, purely as a hobby. When I attempt to find a polynomial's inverse modulo p (in this example p = 3), SymPy always returns negative coefficients, when I want strictly positive coefficients. Here is the code I have. I'll explain what I mean.
import sympy as sym
from sympy import GF
def make_poly(N,coeffs):
"""Create a polynomial in x."""
x = sym.Symbol('x')
coeffs = list(reversed(coeffs))
y = 0
for i in range(N):
y += (x**i)*coeffs[i]
y = sym.poly(y)
return y
N = 7
p = 3
q = 41
f = [1,0,-1,1,1,0,-1]
f_poly = make_poly(N,f)
x = sym.Symbol('x')
Fp = sym.polys.polytools.invert(f_poly,x**N-1,domain=GF(p))
Fq = sym.polys.polytools.invert(f_poly,x**N-1,domain=GF(q))
print('\nf =',f_poly)
print('\nFp =',Fp)
print('\nFq =',Fq)
In this code, f_poly is a polynomial with degree at most 6 (its degree is at most N-1), whose coefficients come from the list f (the first entry in f is the coefficient on the highest power of x, continuing in descending order).
Now, I want to find the inverse polynomial of f_poly in the convolution polynomial ring Rp = (Z/pZ)[x]/(x^N - 1)(Z/pZ)[x] (similarly for q). The output of the print statements at the bottom are:
f = Poly(x**6 - x**4 + x**3 + x**2 - 1, x, domain='ZZ')
Fp = Poly(x**6 - x**5 + x**3 + x**2 + x + 1, x, modulus=3)
Fq = Poly(8*x**6 - 15*x**5 - 10*x**4 - 20*x**3 - x**2 + 2*x - 4, x, modulus=41)
These polynomials are correct in modulus, but I would like to have positive coefficients everywhere, as later on in the algorithm there is some centerlifting involved, so I need to have positive coefficients. The results should be
Fp = x^6 + 2x^5 + x^3 + x^2 + x + 1
Fq = 8x^6 + 26x^5 + 31x^4 + 21x^3 + 40x^2 + 2x + 37
The answers I'm getting are correct in modulus, but I think that SymPy's invert is changing some of the coefficients to negative variants, instead of staying inside the mod.
Is there any way I can update the coefficients of this polynomial to have only positive coefficients in modulus, or is this just an artifact of SymPy's function? I want to keep the SymPy Poly format so I can use some of its embedded functions later on down the line. Any insight would be much appreciated!
This seems to be down to how the finite field object implemented in GF "wraps" integers around the given modulus. The default behavior is symmetric, which means that any integer x for which x % modulo <= modulo//2 maps to x % modulo, and otherwise maps to (x % modulo) - modulo. So GF(10)(5) == 5, whereas GF(10)(6) == -4. You can make GF always map to positive numbers instead by passing the symmetric=False argument:
import sympy as sym
from sympy import GF
def make_poly(N, coeffs):
"""Create a polynomial in x."""
x = sym.Symbol('x')
coeffs = list(reversed(coeffs))
y = 0
for i in range(N):
y += (x**i)*coeffs[i]
y = sym.poly(y)
return y
N = 7
p = 3
q = 41
f = [1,0,-1,1,1,0,-1]
f_poly = make_poly(N,f)
x = sym.Symbol('x')
Fp = sym.polys.polytools.invert(f_poly,x**N-1,domain=GF(p, symmetric=False))
Fq = sym.polys.polytools.invert(f_poly,x**N-1,domain=GF(q, symmetric=False))
print('\nf =',f_poly)
print('\nFp =',Fp)
print('\nFq =',Fq)
Now you'll get the polynomials you wanted. The output from the print(...) statements at the end of the example should look like:
f = Poly(x**6 - x**4 + x**3 + x**2 - 1, x, domain='ZZ')
Fp = Poly(x**6 + 2*x**5 + x**3 + x**2 + x + 1, x, modulus=3)
Fq = Poly(8*x**6 + 26*x**5 + 31*x**4 + 21*x**3 + 40*x**2 + 2*x + 37, x, modulus=41)
Mostly as a note for my own reference, here's how you would get Fp using Mathematica:
Fp = PolynomialMod[Algebra`PolynomialPowerMod`PolynomialPowerMod[x^6 - x^4 + x^3 + x^2 - 1, -1, x, x^7 - 1], 3]
output:
1 + x + x^2 + x^3 + 2 x^5 + x^6
i am trying to fit an exponential curve through three given Points. But i get only very wrong results of fsolve or actual 0. I need this for my Bachelor Thesis so if anyone knows a better solution for the problem, it would be very kind to tell me this solution.
from numpy import *
from scipy.optimize import *
def myFunction(variables):
x1 = 1
y1 = 100
x2 = 5
y2 = 50
x3 = 10
y3 = 1
(a,k,b) = variables
y1 = a*exp(-x1*k)+b
y2 = a*exp(-x2*k)+b
y3 = a*exp(-x3*k)+b
#0 = a*k**2 * exp(-x1+k)
return ([a, k, b])
z = fsolve(myFunction,(1,0.1,5))
print(z)
this is my problem, i need to fit an e function through this 3 given points, and in addition the second derivation of the forumla should be 0
edit: 06.12.17
in some way i have now an improvement with a polynom, but does not really fit like it should.
The second Maximum should not be there.. :D
from numpy import *
from scipy.optimize import *
import matplotlib.pyplot as plt
def myFunction(z):
a = z[0]
b = z[1]
c = z[2]
d = z[3]
e = z[4]
f = z[5]
g = z[6]
x = [0, 10 ,15 ,20 ,50 ,100]
y = [10 ,90 ,100 ,90 ,50 ,10]
s = [0, 10, 1, 0, 0, 0]
F = empty((8))
F[0] = a*x[0]**6 + b*x[0]**5 + c*x[0]**4 + d*x[0]**3 + e*x[0]**2 + f*x[0]**1 + g - y[0]
F[1] = a*x[1]**6 + b*x[1]**5 + c*x[1]**4 + d*x[1]**3 + e*x[1]**2 + f*x[1]**1 + g - y[1]
F[2] = a*x[2]**6 + b*x[2]**5 + c*x[2]**4 + d*x[2]**3 + e*x[2]**2 + f*x[2]**1 + g - y[2]
F[3] = a*x[3]**6 + b*x[3]**5 + c*x[3]**4 + d*x[3]**3 + e*x[3]**2 + f*x[3]**1 + g - y[3]
F[4] = a*x[4]**6 + b*x[4]**5 + c*x[4]**4 + d*x[4]**3 + e*x[4]**2 + f*x[4]**1 + g - y[4]
F[5] = a*x[5]**6 + b*x[5]**5 + c*x[5]**4 + d*x[5]**3 + e*x[5]**2 + f*x[5]**1 + g - y[5]
F[6] = 6*a*x[3]**5 + 5*b*x[3]**4 + 4*c*x[3]**3 + 3*d*x[3]**2 + 2*e*x[3]**1 + f - s[3]
F[7] = 6*a*x[5]**5 + 5*b*x[5]**4 + 4*c*x[5]**3 + 3*d*x[5]**2 + 2*e*x[5]**1 + f - s[5]
return F
zGuess = array([1,1,1,1,1,1,1,1])
z = fsolve(myFunction,zGuess)
print(z)
x_axis = linspace(0,100,100)
y_axis = z[0]*x_axis**6 + z[1]*x_axis**5 + z[2]*x_axis**4 + z[3]*x_axis**3 + z[4]*x_axis**2 + z[5]*x_axis**1 + z[6]
plt.plot(x_axis, y_axis)
plt.show()
edit 07.12.17
the whole signal should look like the data of the second example. But the difficulty is in the part of the first example. My suggestion was to use 2 polynoms, but my prof would prefer an polynom x<20 and an e function x>20. The overlapping of both should also be very smooth.
Well fsolve find the roots of a function, does not really do a non-linear fit. I must admit I don't actually quite get what you want to achieve with your code. If you want to do a nonlinear fit (since you are talking about exponential functions here) you may want to check my notebook here https://github.com/michelucci/Regression-with-Python/blob/master/(Non)%20linear%20fit%20in%20Python.ipynb that I hope can point you in the right direction. It contains first a part on linear regression and then a non-linear tutorial.
You can check curve_fit() python function in the scipy.optimize library. That should help you with what you want to do.
Let me know if that helps you.
You may also want to check this link to better understand what a non-linear fit is https://en.wikipedia.org/wiki/Nonlinear_regression
Best, Umberto
I use Mayavi to plot implicit 3d surfaces and I would like to combine those surfaces into one plot. However, when I do this I get something similar like this:
The code I am using:
import numpy as np
from mayavi import mlab
A=0.24639243776
B=5.39100472027e-17
C=1.71555149594
D=1.72967325617
E=7.50535440036
F=-1.17072847143
G=1.0
x, y, z = np.ogrid[-3:1:100j, -10:1:100j, 0:3:100j]
def Fun (x,y,z, A,B,C,D,E,F,G):
F1 = (x - A + y - B) / 2 + np.sqrt(((x - A - y + B) / 2) ** 2 + C * z ** 2)
F2 = np.sqrt(x*((F*y)/2 + (E*x)/D) + y*((F*x)/2 + (D*y)/E) + G*z**2) - np.sqrt(D*E)
F1 [F1 < 0] = F2 [F1 < 0]
return F1
Fu = Fun (x,y,z,A,B,C,D,E,F,G)
mlab.contour3d(Fu, contours = [0])
mlab.show()
The problem is that no matter how I do it one of the surfaces is very low poly! I had plotted the same in Mathematica and it produces a perfect plot:
I do not expect to get the same quality plot as Mathematica is a commercial product. But at least I would like for both surfaces to be smooth.
If Mayavi is not the right tool for the task, maybe you could recommend something different with which I could achieve the desired result.
Thanks in advance!
I figured it out. The key is to set the surface to None for it to be trimmed. Then the other surface can be drawn in the same fashion. Furthermore for the surface to be plotted according to scale, x,y,z has to be also passed into the contour3d
import numpy as np
from mayavi import mlab
A=0.24639243776
B=5.39100472027e-17
C=1.71555149594
D=1.72967325617
E=7.50535440036
F=-1.17072847143
G=1.0
x, y, z = np.mgrid[-3:1:300j, -10:1:300j, 0:3:300j]
def Fun1 (x,y,z, A,B,C,D,E,F,G):
F1 = (x - A + y - B) / 2 + np.sqrt(((x - A - y + B) / 2) ** 2 + C * z ** 2)
F2 = np.sqrt(x*((F*y)/2 + (E*x)/D) + y*((F*x)/2 + (D*y)/E) + G*z**2) - np.sqrt(D*E)
F1 [F2 > 0.0] = None
return F1
def Fun2 (x,y,z, A,B,C,D,E,F,G):
F1 = (x - A + y - B) / 2 + np.sqrt(((x - A - y + B) / 2) ** 2 + C * z ** 2)
F2 = np.sqrt(x*((F*y)/2 + (E*x)/D) + y*((F*x)/2 + (D*y)/E) + G*z**2) - np.sqrt(D*E)
F2 [F1 > 0.0] = None
return F2
Fu1 = Fun1 (x,y,z,A,B,C,D,E,F,G)
Fu2 = Fun2 (x,y,z,A,B,C,D,E,F,G)
mlab.contour3d(x,y,z,Fu1, contours = [0])
mlab.contour3d(x,y,z,Fu2, contours = [0])
mlab.show()
And here is the result: