Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
cython
Commits
ba79eb61
Commit
ba79eb61
authored
Sep 27, 2015
by
Stefan Behnel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add optimised "chaos" benchmark
parent
188e66ac
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
313 additions
and
0 deletions
+313
-0
Demos/benchmarks/chaos.pxd
Demos/benchmarks/chaos.pxd
+39
-0
Demos/benchmarks/chaos.py
Demos/benchmarks/chaos.py
+274
-0
No files found.
Demos/benchmarks/chaos.pxd
0 → 100644
View file @
ba79eb61
cimport
cython
cdef
extern
from
"math.h"
:
cpdef
double
sqrt
(
double
x
)
@
cython
.
final
cdef
class
GVector
:
cdef
public
double
x
,
y
,
z
cpdef
double
Mag
(
self
)
cpdef
double
dist
(
self
,
GVector
other
)
cpdef
list
GetKnots
(
list
points
,
long
degree
)
@
cython
.
final
cdef
class
Spline
:
cdef
list
knots
cdef
list
points
cdef
long
degree
cpdef
(
long
,
long
)
GetDomain
(
self
)
cpdef
long
GetIndex
(
self
,
u
)
@
cython
.
final
cdef
class
Chaosgame
:
cdef
list
splines
cdef
double
thickness
cdef
double
minx
,
miny
,
maxx
,
maxy
,
height
,
width
cdef
list
num_trafos
cdef
double
num_total
cpdef
tuple
get_random_trafo
(
self
)
cpdef
GVector
transform_point
(
self
,
GVector
point
,
trafo
=*
)
cpdef
truncate
(
self
,
GVector
point
)
cpdef
create_image_chaos
(
self
,
timer
,
long
w
,
long
h
,
long
n
)
Demos/benchmarks/chaos.py
0 → 100644
View file @
ba79eb61
# Copyright (C) 2005 Carl Friedrich Bolz
"""create chaosgame-like fractals
"""
from
__future__
import
division
,
print_function
import
cython
import
time
import
operator
import
optparse
import
random
random
.
seed
(
1234
)
from
functools
import
reduce
if
not
cython
.
compiled
:
from
math
import
sqrt
class
GVector
(
object
):
def
__init__
(
self
,
x
=
0
,
y
=
0
,
z
=
0
):
self
.
x
=
x
self
.
y
=
y
self
.
z
=
z
def
Mag
(
self
):
return
sqrt
(
self
.
x
**
2
+
self
.
y
**
2
+
self
.
z
**
2
)
def
dist
(
self
,
other
):
return
sqrt
((
self
.
x
-
other
.
x
)
**
2
+
(
self
.
y
-
other
.
y
)
**
2
+
(
self
.
z
-
other
.
z
)
**
2
)
@
cython
.
locals
(
self
=
"GVector"
,
other
=
"GVector"
)
def
__add__
(
self
,
other
):
if
not
isinstance
(
other
,
GVector
):
raise
ValueError
(
"Can't add GVector to "
+
str
(
type
(
other
)))
v
=
GVector
(
self
.
x
+
other
.
x
,
self
.
y
+
other
.
y
,
self
.
z
+
other
.
z
)
return
v
@
cython
.
locals
(
self
=
"GVector"
,
other
=
"GVector"
)
def
__sub__
(
self
,
other
):
return
self
+
other
*
-
1
@
cython
.
locals
(
self
=
"GVector"
,
other
=
cython
.
double
)
def
__mul__
(
self
,
other
):
v
=
GVector
(
self
.
x
*
other
,
self
.
y
*
other
,
self
.
z
*
other
)
return
v
__rmul__
=
__mul__
@
cython
.
locals
(
other
=
"GVector"
,
l1
=
cython
.
double
,
l2_
=
cython
.
double
)
def
linear_combination
(
self
,
other
,
l1
,
l2
=
None
):
l2_
=
1
-
l1
if
l2
is
None
else
l2
v
=
GVector
(
self
.
x
*
l1
+
other
.
x
*
l2_
,
self
.
y
*
l1
+
other
.
y
*
l2_
,
self
.
z
*
l1
+
other
.
z
*
l2_
)
return
v
def
__str__
(
self
):
return
"<%f, %f, %f>"
%
(
self
.
x
,
self
.
y
,
self
.
z
)
def
__repr__
(
self
):
return
"GVector(%f, %f, %f)"
%
(
self
.
x
,
self
.
y
,
self
.
z
)
def
GetKnots
(
points
,
degree
):
knots
=
[
0
]
*
degree
+
range
(
1
,
len
(
points
)
-
degree
)
knots
+=
[
len
(
points
)
-
degree
]
*
degree
return
knots
class
Spline
(
object
):
"""Class for representing B-Splines and NURBS of arbitrary degree"""
def
__init__
(
self
,
points
,
degree
=
3
,
knots
=
None
):
"""Creates a Spline. points is a list of GVector, degree is the degree of the Spline."""
if
knots
is
None
:
self
.
knots
=
GetKnots
(
points
,
degree
)
else
:
if
len
(
points
)
>
len
(
knots
)
-
degree
+
1
:
raise
ValueError
(
"too many control points"
)
elif
len
(
points
)
<
len
(
knots
)
-
degree
+
1
:
raise
ValueError
(
"not enough control points"
)
last
=
knots
[
0
]
for
cur
in
knots
[
1
:]:
if
cur
<
last
:
raise
ValueError
(
"knots not strictly increasing"
)
last
=
cur
self
.
knots
=
knots
self
.
points
=
points
self
.
degree
=
degree
def
GetDomain
(
self
):
"""Returns the domain of the B-Spline"""
return
(
self
.
knots
[
self
.
degree
-
1
],
self
.
knots
[
len
(
self
.
knots
)
-
self
.
degree
])
@
cython
.
locals
(
ik
=
cython
.
long
,
ii
=
cython
.
long
,
I
=
cython
.
long
,
ua
=
cython
.
long
,
ub
=
cython
.
long
,
u
=
cython
.
double
)
def
__call__
(
self
,
u
):
"""Calculates a point of the B-Spline using de Boors Algorithm"""
dom
=
self
.
GetDomain
()
if
u
<
dom
[
0
]
or
u
>
dom
[
1
]:
raise
ValueError
(
"Function value not in domain"
)
if
u
==
dom
[
0
]:
return
self
.
points
[
0
]
if
u
==
dom
[
1
]:
return
self
.
points
[
-
1
]
I
=
self
.
GetIndex
(
u
)
d
=
[
self
.
points
[
I
-
self
.
degree
+
1
+
ii
]
for
ii
in
range
(
self
.
degree
+
1
)]
U
=
self
.
knots
for
ik
in
range
(
1
,
self
.
degree
+
1
):
for
ii
in
range
(
I
-
self
.
degree
+
ik
+
1
,
I
+
2
):
ua
=
U
[
ii
+
self
.
degree
-
ik
]
ub
=
U
[
ii
-
1
]
co1
=
(
ua
-
u
)
/
(
ua
-
ub
)
co2
=
(
u
-
ub
)
/
(
ua
-
ub
)
index
=
ii
-
I
+
self
.
degree
-
ik
-
1
d
[
index
]
=
d
[
index
].
linear_combination
(
d
[
index
+
1
],
co1
,
co2
)
return
d
[
0
]
@
cython
.
locals
(
ii
=
cython
.
long
,
I
=
cython
.
long
)
def
GetIndex
(
self
,
u
):
dom
=
self
.
GetDomain
()
for
ii
in
range
(
self
.
degree
-
1
,
len
(
self
.
knots
)
-
self
.
degree
):
if
self
.
knots
[
ii
]
<=
u
<
self
.
knots
[
ii
+
1
]:
I
=
ii
break
else
:
I
=
dom
[
1
]
-
1
return
I
def
__len__
(
self
):
return
len
(
self
.
points
)
def
__repr__
(
self
):
return
"Spline(%r, %r, %r)"
%
(
self
.
points
,
self
.
degree
,
self
.
knots
)
class
Chaosgame
(
object
):
@
cython
.
locals
(
splines
=
list
,
thickness
=
cython
.
double
,
maxlength
=
cython
.
double
,
length
=
cython
.
double
,
curr
=
GVector
,
last
=
GVector
,
p
=
GVector
,
spl
=
Spline
,
t
=
cython
.
double
,
i
=
int
)
def
__init__
(
self
,
splines
,
thickness
=
0.1
):
self
.
splines
=
splines
self
.
thickness
=
thickness
self
.
minx
=
min
([
p
.
x
for
spl
in
splines
for
p
in
spl
.
points
])
self
.
miny
=
min
([
p
.
y
for
spl
in
splines
for
p
in
spl
.
points
])
self
.
maxx
=
max
([
p
.
x
for
spl
in
splines
for
p
in
spl
.
points
])
self
.
maxy
=
max
([
p
.
y
for
spl
in
splines
for
p
in
spl
.
points
])
self
.
height
=
self
.
maxy
-
self
.
miny
self
.
width
=
self
.
maxx
-
self
.
minx
self
.
num_trafos
=
[]
maxlength
=
thickness
*
self
.
width
/
self
.
height
for
spl
in
splines
:
length
=
0
curr
=
spl
(
0
)
for
i
in
range
(
1
,
1000
):
last
=
curr
t
=
1
/
999
*
i
curr
=
spl
(
t
)
length
+=
curr
.
dist
(
last
)
self
.
num_trafos
.
append
(
max
(
1
,
int
(
length
/
maxlength
*
1.5
)))
self
.
num_total
=
reduce
(
operator
.
add
,
self
.
num_trafos
,
0
)
def
get_random_trafo
(
self
):
r
=
random
.
randrange
(
int
(
self
.
num_total
)
+
1
)
l
=
0
for
i
in
range
(
len
(
self
.
num_trafos
)):
if
l
<=
r
<
l
+
self
.
num_trafos
[
i
]:
return
i
,
random
.
randrange
(
self
.
num_trafos
[
i
])
l
+=
self
.
num_trafos
[
i
]
return
len
(
self
.
num_trafos
)
-
1
,
random
.
randrange
(
self
.
num_trafos
[
-
1
])
@
cython
.
locals
(
neighbour
=
"GVector"
,
basepoint
=
"GVector"
,
derivative
=
"GVector"
,
seg_length
=
cython
.
double
,
start
=
cython
.
double
,
end
=
cython
.
double
,
t
=
cython
.
double
)
def
transform_point
(
self
,
point
,
trafo
=
None
):
x
=
(
point
.
x
-
self
.
minx
)
/
self
.
width
y
=
(
point
.
y
-
self
.
miny
)
/
self
.
height
if
trafo
is
None
:
trafo
=
self
.
get_random_trafo
()
start
,
end
=
self
.
splines
[
trafo
[
0
]].
GetDomain
()
length
=
end
-
start
seg_length
=
length
/
self
.
num_trafos
[
trafo
[
0
]]
t
=
start
+
seg_length
*
trafo
[
1
]
+
seg_length
*
x
basepoint
=
self
.
splines
[
trafo
[
0
]](
t
)
if
t
+
1
/
50000
>
end
:
neighbour
=
self
.
splines
[
trafo
[
0
]](
t
-
1
/
50000
)
derivative
=
neighbour
-
basepoint
else
:
neighbour
=
self
.
splines
[
trafo
[
0
]](
t
+
1
/
50000
)
derivative
=
basepoint
-
neighbour
if
derivative
.
Mag
()
!=
0
:
basepoint
.
x
+=
derivative
.
y
/
derivative
.
Mag
()
*
(
y
-
0.5
)
*
\
self
.
thickness
basepoint
.
y
+=
-
derivative
.
x
/
derivative
.
Mag
()
*
(
y
-
0.5
)
*
\
self
.
thickness
else
:
print
(
"r"
,
end
=
''
)
self
.
truncate
(
basepoint
)
return
basepoint
def
truncate
(
self
,
point
):
if
point
.
x
>=
self
.
maxx
:
point
.
x
=
self
.
maxx
if
point
.
y
>=
self
.
maxy
:
point
.
y
=
self
.
maxy
if
point
.
x
<
self
.
minx
:
point
.
x
=
self
.
minx
if
point
.
y
<
self
.
miny
:
point
.
y
=
self
.
miny
def
create_image_chaos
(
self
,
timer
,
w
,
h
,
n
):
im
=
[[
1
]
*
h
for
i
in
range
(
w
)]
point
=
GVector
((
self
.
maxx
+
self
.
minx
)
/
2
,
(
self
.
maxy
+
self
.
miny
)
/
2
,
0
)
times
=
[]
for
_
in
range
(
n
):
t1
=
timer
()
for
i
in
range
(
5000
):
point
=
self
.
transform_point
(
point
)
x
=
(
point
.
x
-
self
.
minx
)
/
self
.
width
*
w
y
=
(
point
.
y
-
self
.
miny
)
/
self
.
height
*
h
x
=
int
(
x
)
y
=
int
(
y
)
if
x
==
w
:
x
-=
1
if
y
==
h
:
y
-=
1
im
[
x
][
h
-
y
-
1
]
=
0
t2
=
timer
()
times
.
append
(
t2
-
t1
)
return
times
def
main
(
n
,
timer
=
time
.
time
):
splines
=
[
Spline
([
GVector
(
1.597350
,
3.304460
,
0.000000
),
GVector
(
1.575810
,
4.123260
,
0.000000
),
GVector
(
1.313210
,
5.288350
,
0.000000
),
GVector
(
1.618900
,
5.329910
,
0.000000
),
GVector
(
2.889940
,
5.502700
,
0.000000
),
GVector
(
2.373060
,
4.381830
,
0.000000
),
GVector
(
1.662000
,
4.360280
,
0.000000
)],
3
,
[
0
,
0
,
0
,
1
,
1
,
1
,
2
,
2
,
2
]),
Spline
([
GVector
(
2.804500
,
4.017350
,
0.000000
),
GVector
(
2.550500
,
3.525230
,
0.000000
),
GVector
(
1.979010
,
2.620360
,
0.000000
),
GVector
(
1.979010
,
2.620360
,
0.000000
)],
3
,
[
0
,
0
,
0
,
1
,
1
,
1
]),
Spline
([
GVector
(
2.001670
,
4.011320
,
0.000000
),
GVector
(
2.335040
,
3.312830
,
0.000000
),
GVector
(
2.366800
,
3.233460
,
0.000000
),
GVector
(
2.366800
,
3.233460
,
0.000000
)],
3
,
[
0
,
0
,
0
,
1
,
1
,
1
])
]
c
=
Chaosgame
(
splines
,
0.25
)
return
c
.
create_image_chaos
(
timer
,
1000
,
1200
,
n
)
if
__name__
==
"__main__"
:
import
util
parser
=
optparse
.
OptionParser
(
usage
=
"%prog [options]"
,
description
=
"Test the performance of the Chaos benchmark"
)
util
.
add_standard_options_to
(
parser
)
options
,
args
=
parser
.
parse_args
()
util
.
run_benchmark
(
options
,
options
.
num_runs
,
main
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment