No performance gain using the JIT compiler - jit

I currently doing some benchmark to test about the JIT compiler for check how much performance gain we can expect between a query with the JIT disabled, one with the JIT enabled and a custom implementation directly inside the codebase of clickhouse-server.
As a base test, I create a table with 10 different columns with the same type, with doing only simple arithmetic operations. This table contains 10 million rows.
The formula is something who can be represented as a / a' + b / b' + c / c' + d / d' + e / e'.
While we can see a big performance improvement using a custom clickhouse function, we cannot see notable performance gain using a JIT compiler who would possibly not creating intermediate columns for doing this kind of operation.
The file that I use for clickhouse performance-test
<test>
<name>Without JIT VS JIT VS custom implementation</name>
<type>loop</type>
<stop_conditions>
<all_of>
<iterations>10</iterations>
</all_of>
</stop_conditions>
<create_query>CREATE TABLE test (a UInt64, a_ UInt64, b UInt64, b_ UInt64, c UInt64, c_ UInt64, d UInt64, d_ UInt64, e UInt64, e_ UInt64) Engine = Memory</create_query>
<fill_query>INSERT INTO test SELECT number, number, number, number, number, number, number, number, number, number from system.numbers LIMIT 10000000</fill_query>
<query>
SELECT
a / a_ + b / b_ + c / c_ + d / d_ + e / e_
FROM
test
SETTINGS
compile_expressions = 0;
</query>
<query>
SELECT
a / a_ + b / b_ + c / c_ + d / d_ + e / e_
FROM
test
SETTINGS
compile_expressions = 1;
</query>
<query>
SELECT custom_implementation(a, a_, b, b_, c, c_, d, d_, e, e_) FROM test
</query>
<drop_query>DROP TABLE IF EXISTS test</drop_query>
</test>
output
{
...
"runs": [
{
"bytes_per_second": 3477655258.582295,
"min_time": 0.224000,
"quantiles": {
"0.1": 0.224292,
"0.2": 0.224770,
"0.3": 0.225735,
"0.4": 0.227052,
"0.5": 0.228536,
"0.6": 0.229970,
"0.7": 0.232717,
"0.8": 0.237127,
"0.9": 0.237441,
"0.95": 0.238033,
"0.99": 0.238508,
"0.999": 0.238614,
"0.9999": 0.238625
},
"queries_per_second": 4.347069,
"query": "\n SELECT\n a / a_ + b / b_ + c / c_ + d / d_ + e / e_\n FROM\n test\n SETTINGS\n compile_expressions = 0;\n ",
"query_index": 0,
"rows_per_second": 43470690.732279,
"total_time": 2.300401
},
{
"bytes_per_second": 3507592718.689820,
"min_time": 0.224000,
"quantiles": {
"0.1": 0.224705,
"0.2": 0.225049,
"0.3": 0.225372,
"0.4": 0.225570,
"0.5": 0.225661,
"0.6": 0.225992,
"0.7": 0.226896,
"0.8": 0.229604,
"0.9": 0.236507,
"0.95": 0.237723,
"0.99": 0.238695,
"0.999": 0.238913,
"0.9999": 0.238935
},
"queries_per_second": 4.384491,
"query": "\n SELECT\n a / a_ + b / b_ + c / c_ + d / d_ + e / e_\n FROM\n test\n SETTINGS\n compile_expressions = 1;\n ",
"query_index": 1,
"rows_per_second": 43844908.983623,
"total_time": 2.280767
},
{
"bytes_per_second": 6126143858.553072,
"min_time": 0.117000,
"quantiles": {
"0.1": 0.124773,
"0.2": 0.125735,
"0.3": 0.126914,
"0.4": 0.127659,
"0.5": 0.129169,
"0.6": 0.131099,
"0.7": 0.132744,
"0.8": 0.136030,
"0.9": 0.142146,
"0.95": 0.142186,
"0.99": 0.142218,
"0.999": 0.142225,
"0.9999": 0.142226
},
"queries_per_second": 7.657680,
"query": "\n SELECT custom_implementation(a, a_, b, b_, c, c_, d, d_, e, e_) FROM test\n ",
"query_index": 2,
"rows_per_second": 76576798.231913,
"total_time": 1.305879
}
],
...
}
Does the JIT compiler compile the expression only in some particular cases?

Related

Exact Line Search Algorithm

I am trying to implement a simple line-search algorithm in Julia. I am new to Julia programming, so I am learning it on the go. I'd like to ask for some help, if possible, to correct an error while running the code.
Source code.
using LinearAlgebra
function bracket_minimum(f, x = 0, s = 1e-2, k = 2.0)
a, fa = x, f(x)
b, fb = x + s, f(x + s)
if(fb > fa)
a, b = b, a
fa, fb = fb, fa
s = -s
end
while(true)
c, fc = b + s, f(b + s)
if(fb < fc)
return a < c ? (a, c) : (c, a)
else
a, fa, b, fb = b, fb, c, fc
s *= k
end
end
end
function bisection(f, a₀, b₀, ϵ)
function D(f,a)
# Approximate the first derivative using central differences
h = 0.001
return (f(a + h) - f(a - h))/(2 * h)
end
a = a₀
b = b₀
while((b - a) > ϵ)
c = (a + b)/2.0
if D(f,c) > 0
b = c
else
a = c
end
end
return (a,b)
end
function line_search(f::Function, x::Vector{Float64}, d::Vector{Float64})
println("Hello")
objective = α -> f(x + α*d)
a, b = bracket_minimum(objective)
α = bisection(objective, a, b, 1e-5)
return α, x + α*d
end
f(x) = sin(x[1] * x[2]) + exp(x[2] + x[3]) - x[3]
x = [1,2,3]
d = [0, -1, -1]
α, x_min = line_search(f, x, d)
I am getting a Linear algebraic error, so I think I must not be passing vectors correctly or perhaps I am not doing scalar-vector multiplication correctly. But, I was having a hard-time figuring out. If I step through the code, it fails on the function call line_search(f,x,d) and does not even enter inside the function body.
Error description.
ERROR: MethodError: no method matching *(::Tuple{Float64,Float64}, ::Array{Int64,1})
Closest candidates are:
*(::Any, ::Any, ::Any, ::Any...) at operators.jl:538
*(::Adjoint{var"#s828",var"#s8281"} where var"#s8281"<:(AbstractArray{T,1} where T) where var"#s828"<:Number, ::AbstractArray{var"#s827",1} where var"#s827"<:Number) at C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.5\LinearAlgebra\src\adjtrans.jl:283
*(::Transpose{T,var"#s828"} where var"#s828"<:(AbstractArray{T,1} where T), ::AbstractArray{T,1}) where T<:Real at C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.5\LinearAlgebra\src\adjtrans.jl:284
Here is a fix in the code (I have cleaned up several stylistic things, but the key problem that your bisection returned a tuple not a value - I have changed it to return the center of the bracketing interval):
function bracket_minimum(f, x = 0.0, s = 1e-2, k = 2.0)
a, fa = x, f(x)
b, fb = x + s, f(x + s)
if fb > fa
a, b = b, a
fa, fb = fb, fa
s = -s
end
while true
s *= k
c, fc = b + s, f(b + s)
if fb < fc
return minmax(a, c)
else
a, fa, b, fb = b, fb, c, fc
end
end
end
function bisection(f, a₀, b₀, ϵ)
function D(f, a)
# Approximate the first derivative using central differences
h = 0.001
return (f(a + h) - f(a - h)) / (2 * h)
end
a = a₀
b = b₀
while (b - a) > ϵ
c = (a + b) / 2.0
if D(f, c) > 0
b = c
else
a = c
end
end
return (a + b) / 2 # this was changed
end
function line_search(f::Function, x::Vector{Float64}, d::Vector{Float64})
#assert length(x) == length(d)
objective(α) = f(x .+ α .* d)
a, b = bracket_minimum(objective)
α = bisection(objective, a, b, 1e-5)
return α, x .+ α .* d
end
f(x) = sin(x[1] * x[2]) + exp(x[2] + x[3]) - x[3]
x = [1.0, 2.0, 3.0]
d = [0.0, -1.0, -1.0]
α, x_min = line_search(f, x, d)
I was not commenting on the algorithm, as I assume you are writing this as a programming exercise and you are not trying to write the fastest and most robust algorithm.

How to pattern match 0.0 in SML? [duplicate]

This question already has an answer here:
Why can't I compare reals in Standard ML?
(1 answer)
Closed 4 years ago.
I have the following code:
datatype complex = RealImg of real * real | Infinity;
fun divisionComplex(RealImg(a, b), RealImg(0.0, 0.0)) = Infinity
fun divisionComplex(RealImg(a, b), RealImg(c, d)) =
RealImg ((a * c + b * d) / (c * c + d * d), ((b * c) - (a * d))/ (c* c + d * d))
However it fails with this:
Error: syntax error: inserting EQUALOP
I am very confused. Why does this happen? I know that I can't compare two reals in SML, but how am I supposed to do pattern matching with 0?
As you said SML doesn't allow to pattern match real numbers, but recommends to use Real.== instead or compare the difference between these number against some delta.
What about just using a mere if statement for this? (also some Infinity cases added just to make the match against function params exhaustive, but feel free to change it, because it doesn't pretend to be correct)
datatype complex = RealImg of real * real | Infinity;
fun divisionComplex(Infinity, _) = Infinity
| divisionComplex(_, Infinity) = Infinity
| divisionComplex(RealImg(a, b), RealImg(c, d)) =
if Real.== (c, 0.0) andalso Real.== (d, 0.0)
then Infinity
else
RealImg ((a * c + b * d) / (c * c + d * d), ((b * c) - (a * d))/ (c* c + d * d))

Unclassified statement at (1) in a mathematical expression

My first Fortran lesson is to plot the probability density function of the radial Sturmian functions. In case you are interested, the radial Sturmian functions are used to graph the momentum space eigenfunctions for the hydrogen atom.
In order to produce these radial functions, one needs to first produce some polynomials called the Gegenbauer polynomials, denoted
Cba(x),
where a and b should be stacked atop each other. One needs these polynomials because the Sturmians (let's call them R_n,l) are defined like so,
R_n,l(p) = N pl⁄(p2 + k2)l+2 Cn - l - 1l + 1(p2 - k2⁄p2 + k2),
where N is a normalisation constant, p is the momentum, n is the principle quantum number, l is the angular momentum and k is a constant. The normalisation constant is there so that when I come to square this function, it will produce a probability distribution for the momentum of the electron in a hydrogen atom.
Gegenbauer polynomials are generated using the following recurrence relation:
Cnl(x) = 1⁄n[2(l + n - 1) x Cn - 1l(x) - (2l + n - 2)Cn - 2l(x)],
with C0l(x) = 1 and C1l(x) = 2lx, as you may have noticed, l is fixed but n is not. At the start of my program, I will specify both l and n and work out the Gegenbauer polynomial I need for the radial function I wish to plot.
The problems I am having with my code at the moment are all in my subroutine for working out the value of the Gegenbauer polynomial Cn-l-1l+1(p2 - k2⁄p2 + k2) for incremental values of p between 0 and 3. I keep getting the error
Unclassified statement at (1)
but I cannot see what the issue is.
program Radial_Plot
implicit none
real, parameter :: pi = 4*atan(1.0)
integer, parameter :: top = 1000, l = 50, n = 100
real, dimension(1:top) :: x, y
real increment
real :: a=0.0, b = 2.5, k = 0.3
integer :: i
real, dimension(1:top) :: C
increment = (b-a)/(real(top)-1)
x(1) = 0.0
do i = 2, top
x(i) = x(i-1) + increment
end do
Call Gegenbauer(top, n, l, k, C)
y = x*C
! y is the function that I shall be plotting between values a and b.
end program Radial_Plot
Subroutine Gegenbauer(top1, n1, l1, k1, CSub)
! This subroutine is my attempt to calculate the Gegenbauer polynomials evaluated at a certain number of values between c and d.
implicit none
integer :: top1, i, j, n1, l1
real :: k1, increment1, c, d
real, dimension(1:top1) :: x1
real, dimension(1:n1 - l1, 1:top1) :: C1
real, dimension(1:n1 - l1) :: CSub
c = 0.0
d = 3.0
k1 = 0.3
n1 = 50
l1 = 25
top1 = 1000
increment1 = (d - c)/(real(top1) - 1)
x1(1) = 0.0
do i = 2, top1
x1(i) = x1(i-1) + increment1
end do
do j = 1, top1
C1(1,j) = 1
C1(2,j) = 2(l1 + 1)(x1(i)^2 - k1^2)/(x1(i)^2 + k1^2)
! All the errors occurring here are all due to, and I quote, 'Unclassifiable statement at (1)', I can't see what the heck I have done wrong.
do i = 3, n1 - l1
C1(i,j) = 2(((l1 + 1)/n1) + 1)(x1(i)^2 - k1^2)/(x1(i)^2 + k1^2)C1(i,j-1) - ((2(l1+1)/n1) + 1)C1(i,j-2)
end do
CSub(j) = Cn(n1 - l1,j)^2
end do
return
end Subroutine Gegenbauer
As francesalus correctly pointed out, the problem is because you use ^ instead of ** for exponentiation. Additionally, you do not put * between the terms you are multiplying.
C1(1,j) = 1
C1(2,j) = 2*(l1 + 1)*(x1(i)**2 - k1**2)/(x1(i)**2 + k1**2)
do i = 3, n1 - l1
C1(i,j) = 2 * (((l1 + 1)/n1) + 1) * (x1(i)**2 - k1**2) / &
(x1(i)**2 + k1**2)*C1(i,j-1) - ((2(l1+1)/n1) + 1) * &
C1(i,j-2)
end do
CSub(j) = Cn(n1 - l1,j)**2
Since you are beginning I have some advice. Learn to put all subroutines and functions to modules (unless they are internal). There is no reason for the return statement at the and of the subroutine, similarly as a stop statement isn't necessary at the and of the program.

TULIP Trilateration in 2-D algorithm in simpler form

I found an algorithm to do trilateration in 2-D this link. But the formulas are too complicated. What is happening here? Can you please break it down to terms like dot product, cross product, distance etc?
Let P be the unknown point. (Bold for 2D vectors.)
Write the implicit equations of circles 1 and 2:
(P - P1)² = d1²
(P - P2)² = d2²
Substract memberwise and rearrange:
2.(P2 - P1).P = d1² - d2² + P2² - P1²
Similarly with circles 1 and 3:
2.(P3 - P1).P = d1² - d3² + P3² - P1²
Looking closely, you will notice that this forms a system of two linear equations in two unknowns:
2.(X2 - X1).X + 2.(Y2 - Y1).Y = d1² - d2² + P2² - P1²
2.(X3 - X1).X + 2.(Y3 - Y1).Y = d1² - d3² + P3² - P1²
Use Cramer's rule, or if you insist on using vector calculus, work it out as follows.
Rewrite the system as:
A.P = a
B.P = b
Compute vectors perpendicular to A and B in the xy plane, using cross products A' = A /\ 1z and B' = B /\ 1z, and express P as a linear combination of these:
P = u . A' + v . B'
Performing a dot product with A and B gives, after simplification:
A.P = a = v . A.B'
B.P = b = u . B.A'
Note that A.B' = A.(B /\ 1z) = 1z.(A /\ B) = -1z.(B /\ A) = -B.(A /\ 1z) = -B.A' (mixed product).
All in all:
P = [ (- b.A + a.B) /\ 1z ] / [ 1z.(A /\ B) ]
(which is a rewrite of Cramer's result.)

Haskell and Quadratics

I have to write a program to solve quadratics, returning a complex number result.
I've gotten so far, with defining a complex number, declaring it to be part of num, so +,- and * - ing can take place.
I've also defined a data type for a quadratic equation, but im now stuck with the actual solving of the quadratic. My math is quite poor, so any help would be greatly appreciated...
data Complex = C {
re :: Float,
im :: Float
} deriving Eq
-- Display complex numbers in the normal way
instance Show Complex where
show (C r i)
| i == 0 = show r
| r == 0 = show i++"i"
| r < 0 && i < 0 = show r ++ " - "++ show (C 0 (i*(-1)))
| r < 0 && i > 0 = show r ++ " + "++ show (C 0 i)
| r > 0 && i < 0 = show r ++ " - "++ show (C 0 (i*(-1)))
| r > 0 && i > 0 = show r ++ " + "++ show (C 0 i)
-- Define algebraic operations on complex numbers
instance Num Complex where
fromInteger n = C (fromInteger n) 0 -- tech reasons
(C a b) + (C x y) = C (a+x) (b+y)
(C a b) * (C x y) = C (a*x - b*y) (b*x + b*y)
negate (C a b) = C (-a) (-b)
instance Fractional Complex where
fromRational r = C (fromRational r) 0 -- tech reasons
recip (C a b) = C (a/((a^2)+(b^2))) (b/((a^2)+(b^2)))
root :: Complex -> Complex
root (C x y)
| y == 0 && x == 0 = C 0 0
| y == 0 && x > 0 = C (sqrt ( ( x + sqrt ( (x^2) + 0 ) ) / 2 ) ) 0
| otherwise = C (sqrt ( ( x + sqrt ( (x^2) + (y^2) ) ) / 2 ) ) ((y/(2*(sqrt ( ( x + sqrt ( (x^2) + (y^2) ) ) / 2 ) ) ) ) )
-- quadratic polynomial : a.x^2 + b.x + c
data Quad = Q {
aCoeff, bCoeff, cCoeff :: Complex
} deriving Eq
instance Show Quad where
show (Q a b c) = show a ++ "x^2 + " ++ show b ++ "x + " ++ show c
solve :: Quad -> (Complex, Complex)
solve (Q a b c) = STUCK!
EDIT: I seem to have missed out the whole point of using my own complex number datatype is to learn about custom datatypes. I'm well aware that i could use complex.data. Any help that could be given using my solution so far would be greatly appreciated.\
EDIT 2: It seems that my initial question was worded horribly. I'm aware that the quadratic formula will return both (or just the one) root to me. Where I am having trouble is returning these roots as a (complex, complex) tuple with the code above.
I'm well aware that I could use the built in quadratic functions as have been displayed below, but this is not the exercise. The idea behind the exercise, and creating ones own complex number data type, is to learn about custom data types.
Like newacct said, it's just the quadratic equation:
(-b +- sqrt(b^2 - 4ac)) / 2a
module QuadraticSolver where
import Data.Complex
data Quadratic a = Quadratic a a a deriving (Show, Eq)
roots :: (RealFloat a) => Quadratic a -> [ Complex a ]
roots (Quadratic a b c) =
if discriminant == 0
then [ numer / denom ]
else [ (numer + root_discriminant) / denom,
(numer - root_discriminant) / denom ]
where discriminant = (b*b - 4*a*c)
root_discriminant = if (discriminant < 0)
then 0 :+ (sqrt $ -discriminant)
else (sqrt discriminant) :+ 0
denom = 2*a :+ 0
numer = (negate b) :+ 0
in practice:
ghci> :l QuadraticSolver
Ok, modules loaded: QuadraticSolver.
ghci> roots (Quadratic 1 2 1)
[(-1.0) :+ 0.0]
ghci> roots (Quadratic 1 0 1)
[0.0 :+ 1.0,(-0.0) :+ (-1.0)]
And adapting to use your terms:
solve :: Quad -> (Complex, Complex)
solve (Q a b c) = ( sol (+), sol (-) )
where sol op = (op (negate b) $ root $ b*b - 4*a*c) / (2 * a)
Although I haven't tested that code
Since Haskell's sqrt can also handle complex numbers, rampion's solution can even be further simplified:
import Data.Complex
-- roots for quadratic equations with complex coefficients
croots :: (RealFloat a) =>
(Complex a) -> (Complex a) -> (Complex a) -> [Complex a]
croots a b c
| disc == 0 = [solution (+)]
| otherwise = [solution (+), solution (-)]
where disc = b*b - 4*a*c
solution plmi = plmi (-b) (sqrt disc) / (2*a)
-- roots for quadratic equations with real coefficients
roots :: (RealFloat a) => a -> a -> a -> [Complex a]
roots a b c = croots (a :+ 0) (b :+ 0) (c :+ 0)
You can also use this croots function with your own datatype, if you change the types to fit your implementation (and call your root function instead of sqrt).

Resources