itextsharp pdf to image c# : Best way to make pdf forms Library application component asp.net azure wpf mvc book40-part1788

G.2 MigratingscalarPythoncodetoCython
817
G.2MigratingscalarPythoncodetoCython
G.2.1AplainCythonimplementation
ACythonprogramstartswiththescalarPythonimplementation,but
allvariablesarespecifiedwiththeirtypes,usingCython’svariabledecla-
rationsyntax,likecdef int M = 0whereweinstandardPythonjust
write M = 0.Addingsuch variable declarationsin the scalar Python
implementationisstraightforward:
import random
def dice6_cy1(int N, , int ndice, int t nsix):
cdef int M M = = 0
# no of successful events
cdef int six, , r
cdef double p
for i i in range(N):
# repeat N N experiments
six = = 0
# how w many dice e with h six eyes?
for j j in range(ndice):
r = random.randint(1, 6) ) # # roll l die no. j
if r r == 6:
six += 1
if six >= nsix:
# successful event?
M += 1
p = = float(M)/N
return p
Thiscodemustbeputinaseparatefilewithextension.pyx.Running
CythononthisfiletranslatestheCythoncodetoC.Thereafter,theC
codemustbecompiledandlinkedtoformasharedlibrary,whichcanbe
importedinPythonasamodule.Allthesetasksarenormallyautomated
byasetup.pyscript.Letthedice6_cy1functionabovebestoredina
file dice6.pyx. A proper setup.py script looks as follows:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
setup(
name=’Monte Carlo simulation’,
ext_modules=[Extension(’_dice6_cy’, [’dice6.pyx’],)],
cmdclass={’build_ext’: build_ext},
)
Running
Terminal
Terminal> python setup.py build_ext --inplace
generates the C code and creates a (shared library) file_dice6_cy.so
(known as a C extension module) which can be loaded into Python as a
module with name _dice6_cy:
from _dice6_cy import dice6_cy1
import time
t0 = time.clock()
p = dice6_cy1(N, ndice, nsix)
t1 = time.clock()
print t1 - t0
Best way to make pdf forms - C# PDF Field Edit Library: insert, delete, update pdf form field in C#.net, ASP.NET, MVC, Ajax, WPF
Online C# Tutorial to Insert, Delete and Update Fields in PDF Document
edit pdf form; pdf create fillable form
Best way to make pdf forms - VB.NET PDF Field Edit library: insert, delete, update pdf form field in vb.net, ASP.NET, MVC, Ajax, WPF
How to Insert, Delete and Update Fields in PDF Document with VB.NET Demo Code
can reader edit pdf forms; change font size in pdf form field
818
G Migrating Python to compiled code
We refer to this implementation as Cython random.randint. Although
most of the statements in thedice6_cy1 function are turned into plain
and fast C code, the speed is not much improved compared with the
original scalar Python code.
To investigate what takes time in this Cython implementation, we can
perform a profiling. The template for profiling a Python function whose
call syntax is stored in some string statement, reads
import cProfile, pstats
cProfile.runctx(statement, globals(), locals(), ’tmp_profile.dat’)
s = pstats.Stats(’tmp_profile.dat’)
s.strip_dirs().sort_stats(’time’).print_stats(30)
Data from the profiling are here stored in the filetmp_profile.dat. Our
interest now is the dice6_cy1 function so we set
statement = ’dice6_cy1(N, ndice, nsix)’
In addition, a Cython file in which there are functions we want to profile
must start with the line
# cython: profile=True
to turn on profiling when creating the extension module. The profiling
output from the present example looks like
5400004 function calls in 7.525 CPU seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
1800000
4.511
0.000
4.863
0.000 random.py:160(randrange)
1800000
1.525
0.000
6.388
0.000 random.py:224(randint)
1
1.137
1.137
7.525
7.525 dice6.pyx:6(dice6_cy1)
1800000
0.352
0.000
0.352
0.000 {method ’random’ ...
1
0.000
0.000
7.525
7.525 {dice6_cy.dice6_cy1}
We easily see that it is the call torandom.randint that consumes almost
all the time. The reason is that the generated C code must call a Python
module (random), which implies a lot of overhead. The C code should
only call plain C functions, or if Python functions must be called, they
should involve so much computations that the overhead in calling Python
from C is negligible.
Instead of profiling the code to uncover inefficient constructs we can
generate a visual representation of how the Python code is translated to
C. Running
Terminal
Terminal> cython -a dice6.pyx
creates a filedice6.html which can be loaded into a web browser to
inspect what Cython has done with the Python code.
Online Convert PDF file to Tiff. Best free online PDF Tif
We try to make it as easy as possible to convert your PDF files to Tiff. tool, which can perform high-fidelity PDF to TIFF conversion in an easy way.
best program to create pdf forms; adding text fields to pdf
VB.NET TWAIN: VB Code on Image TWAIN Acquisition Object of
perfectly designated to offer users the best image TWAIN Following products features and benefits make RasterEdge VB TWAIN scanned image into the way of local
change font pdf fillable form; create a pdf form that can be filled out
G.2 Migrating scalar Python code to Cython
819
White lines indicate that the Python code is translated into C code,
while the yellow lines indicate that the generated C code must make
calls back to Python (using the Python C API, which implies overhead).
Here, therandom.randint call is in yellow, so this call is not translated
to efficient C code.
G.2.2 A better Cython implementation
To speed up the previous Cython code, we have to get rid of the
random.randint call everytime we e need d a random variable. Either
we must call some C function for generating a random variable or we
must create a bunch of random numbers simultaneously as we did in
the vectorized functions shown above. We first try the latter well-known
strategy and apply thenumpy.random module to generate all the random
numbers we need at once:
import numpy as np
cimport numpy as np
@cython.boundscheck(False) # turn off array bounds check
@cython.wraparound(False)
# turn off negative indices ([-1,-1])
def dice6_cy2(int N, int ndice, int nsix):
# Use numpy to generate all random numbers
...
cdef np.ndarray[np.int_t, ndim=2, mode=’c’] eyes = \
np.random.random_integers(1, 6, (N, ndice))
This code needs some explanation. Thecimport statement imports a
special version of numpy for Cython and is needed after the standard
numpyimport.Thedeclarationofthearrayofrandomnumberscould
just go as
VB.NET Create PDF Library SDK to convert PDF from other file
Best VB.NET component to convert Microsoft Office Word, Excel Creating a PDF document is a good way to share your ideas because you can make sure that
changing font size in pdf form field; change tab order in pdf form
VB.NET TIFF: An Easy VB.NET Solution to Delete or Remove TIFF File
delete from a TIFF file in an easy way. appreciate your online user guide." Best regards, Charles but fortunately your technical personnel has make it correct
create a form in pdf from word; adding form fields to pdf files
820
G Migrating Python to compiled code
cdef np.ndarray eyes = np.random.random_integers(1, 6, (N, ndice))
However, the processing of theeyes array will then be slow because
Cython does not have enough information about the array. To generate
optimal C code, we must provide information on the element types in
the array, the number of dimensions of the array, that the array is stored
in contiguous memory, that we do not want the overhead of checking
whether indices are within their bounds or not, and that we do not
need negative indices (which slows down array indexing). The latter two
properties are taken care of by the@cython.boundscheck(False) and
the@cython.wraparound(False) statements (decorators) right before
the function, respectively, while the rest of the information is specified
within square brackets in thecdef np.ndarray declaration. Inside the
brackets,np.int_t denotes integer array elements (np.int is the usual
data type object, butnp.int_t is a Cython precompiled version of this
object),ndim=2 tells that the array has two dimensions (indices), and
mode=’c’indicatescontiguousstorageofthearray.Withallthisextra
information, Cython can generate C code that works withnumpy arrays
as efficiently as native C arrays.
The rest of the code is a plain copy of thedice6_py function, but with
the random.randint call replaced by an array look-upeyes[i,j] to
retrieve the next random number. The two loops will now be as efficient
as if they were coded directly in pure C.
The complete code for the efficient version of thedice6_cy1 function
looks as follows:
import numpy as np
cimport numpy as np
import cython
@cython.boundscheck(False) # turn off array bounds check
@cython.wraparound(False)
# turn off negative indices ([-1,-1])
def dice6_cy2(int N, int ndice, int nsix):
# Use numpy to generate all random numbers
cdef int M = 0
# no of successful events
cdef int six, r
cdef double p
cdef np.ndarray[np.int_t, ndim=2, mode=’c’] eyes = \
np.random.random_integers(1, 6, (N, ndice))
for i in range(N):
six = 0
# how many dice with six eyes?
for j in range(ndice):
r = eyes[i,j]
# roll die no. j
if r == 6:
six += 1
if six >= nsix:
# successful event?
M += 1
p = float(M)/N
return p
This Cython implementation is named Cython numpy.random.
The disadvantage with thedice6_cy2 function is thatlargesimulations
(largeN) also require large amounts of memory, which usually limits
the possibility for high accuracy much more than the CPU time. It
VB.NET Image: Tutorial for Converting Image and Document in VB.NET
VB.NET Image Conversion SDK is your best choice for SDK supports multiple image conversions in a simple way. to your VB.NET application, please make sure that
adding images to pdf forms; allow users to save pdf form
G.3 Migrating code to C
821
would be advantageous to have a fast random number generator a la
random.randintinC.TheClibrary stdlibhasageneratorofrandom
integers,rand(), generating numbers from 0 to upRAND_MAX. Both the
randfunctionandthe RAND_MAXintegerareeasytoaccessinaCython
program:
from libc.stdlib cimport rand, RAND_MAX
r = 1 + int(6.0*rand()/RAND_MAX) # random integer 1,...,6
Note thatrand() returns an integer so we must avoid integer division
by ensuring that the denominator is a real number. We also need to
explicitly convert the resulting real fraction toint sincer is declared as
int.
With this way of generating random numbers we can create a version
ofdice6_cy1 that is as fast asdice6_cy, but avoids all the memory
demands and the somewhat complicated array declarations of the latter:
from libc.stdlib cimport rand, RAND_MAX
def dice6_cy3(int N, int ndice, int nsix):
cdef int M = 0
# no of successful events
cdef int six, r
cdef double p
for i in range(N):
six = 0
# how many dice with six eyes?
for j in range(ndice):
# Roll die no. j
r = 1 + int(6.0*rand()/RAND_MAX)
if r == 6:
six += 1
if six >= nsix:
# successful event?
M += 1
p = float(M)/N
return p
This final Cython implementation will be referred to as Cython
stdlib.rand.
G.3 Migrating code to C
G.3.1 Writing a C program
A natural next improvement would be to program the Monte Carlo
simulation loops directly in a compiled programming language, which
guarantees optimal speed. Here we choose the C programming language
for this purpose. The C version of ourdice6 function and an associated
main program take the form
#include <stdio.h>
#include <stdlib.h>
double dice6(int N, int ndice, int nsix)
{
int M = 0;
822
G Migrating Python to compiled code
int six, r, i, j;
double p;
for (i = 0; i < N; i++) {
six = 0;
for (j = 0; j < ndice; j++) {
r = 1 + rand()/(RAND_MAX*6.0); /* roll die no. j */
if (r == 6)
six += 1;
}
if (six >= nsix)
M += 1;
}
p = ((double) M)/N;
return p;
}
int main(int nargs, const char* argv[])
{
int N = atoi(argv[1]);
int ndice = 6;
int nsix = 3;
double p = dice6(N, ndice, nsix);
printf("C code: N=%d, p=%.6f\n", N, p);
return 0;
}
This code is placed in a file dice6_c.c. The file can typically be
compiled and run by
Terminal
Terminal> gcc -O3 -o dice6.capp dice6_c.c
Terminal> ./dice6.capp 1000000
This solution is later referred to as C program.
G.3.2 Migrating loops to C code via F2PY
Instead of programming the whole application in C, we may consider
migrating the loops to the C functiondice6 shown above and then have
the rest of the program (essentially the calling main program) in Python.
This is a convenient solution if we were to do many other, less CPU time
critical things for convenience in Python.
There are many alternative techniques for calling C functions from
Python. Here we shall explain two. The first applies the programf2py to
generate the necessary code that glues Python and C. Thef2py program
was actually made for gluing Python and Fortran, but it can work with C
too. We need a specification of the C function to call in terms of a Fortran
90 module. Such a module can be written by hand, butf2py can also
generate it. To this end, we make a Fortran filedice6_c_signature.f
with the signature of the C function written in Fortran 77 syntax with
some annotations:
real*8 function dice6(n, ndice, nsix)
Cf2py intent(c) dice6
integer n, ndice, nsix
Cf2py intent(c) n, ndice, nsix
return
end
G.3 Migrating code to C
823
The annotationsintent(c) are necessary to tellf2py that the Fortran
variables are to be treated as plain C variables and not as pointers (which
is the default interpretation of variables in Fortran). The C2fpy are
special comment lines thatf2py recognizes, and these lines are used
to provide extra information tof2py which have no meaning in plain
Fortran 77.
We must runf2py to generate a.pyf file with a Fortran 90 module
specification of the C function to call:
Terminal
Terminal> f2py -m _dice6_c1 -h dice6_c.pyf \
dice6_c_signature.f
Here_dice6_c1 is the name of the module with the C function that is
to be imported in Python, anddice6_c.pyf is the name of the Fortran
90 module file to be generated. Programmers who know Fortran 90 may
want to write the dice6_c.pyf file by hand.
The next step is to use the information indice6_c.pyf to generate
a (C extension) module _dice6_c1. Fortunately,f2py generates the
necessary code, and compiles and links the relevant files, to form a shared
library file _dice6_c1.so, by a short command:
Terminal
Terminal> f2py -c dice6_c.pyf dice6_c.c
We can now test the module:
>>> import _dice6_c1
>>> print dir(_dice6_c1) # module contents
[’__doc__’, ’__file__’, ’__name__’, ’__package__’,
’__version__’, ’dice6’]
>>> print _dice6_c1.dice6.__doc__
dice6 - Function signature:
dice6 = dice6(n,ndice,nsix)
Required arguments:
n : input int
ndice : input int
nsix : input int
Return objects:
dice6 : float
>>> _dice6_c1.dice6(N=1000, ndice=4, nsix=2)
0.145
The method of calling the C function dice6 via anf2py generated
module is referred to as C via f2py.
G.3.3 Migrating loops to C code via Cython
The Cython tool can also be used to call C code, not only generating C
code from the Cython language. Our C code is in the filedice6_c.c, but
for Cython to see this code we need to create a header filedice6_c.h
824
G Migrating Python to compiled code
listing the definition of the function(s) we want to call from Python. The
header file takes the form
extern double dice6(int N, int ndice, int nsix);
The next step is to make a.pyx file with a definition of the C function
from the header file and a Python function that calls the C function:
cdef extern from "dice6_c.h":
double dice6(int N, int ndice, int nsix)
def dice6_cwrap(int N, int ndice, int nsix):
return dice6(N, ndice, nsix)
Cython must use this file, nameddice6_cwrap.pyx, to generate C
code, which is to be compiled and linked with thedice6_c.c code. All
this is accomplished in a setup.py script:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
sources = [’dice6_cwrap.pyx’, ’dice6_c.c’]
setup(
name=’Monte Carlo simulation’,
ext_modules=[Extension(’_dice6_c2’, sources)],
cmdclass={’build_ext’: build_ext},
)
This setup.py script is run as
Terminal
Terminal> python setup.py build_ext --inplace
resulting in a shared library file_dice6_c2.so, which can be loaded into
Python as a module:
>>> import _dice6_c2
>>> print dir(_dice6_c2)
[’__builtins__’, ’__doc__’, ’__file__’, ’__name__’,
’__package__’, ’__test__’, ’dice6_cwrap’]
We see that the module contains the functiondice6_cwrap, which was
made to call the underlying C function dice6.
G.3.4 Comparing efficiency
All the files corresponding to the various techniques described above
are available in the directorysrc/cython. A filemake.sh performs all
the compilations, whilecompare.py runs all methods and prints out the
CPU time required by each method, normalized by the fastest approach.
The results forN = 450,000 are listed below (MacBook Air running
Ubuntu in a VMWare Fusion virtual machine).
G.3 Migrating code to C
825
Method
Timing
Cprogram
1.0
Cython stdlib.rand
1.2
Cython numpy.random
1.2
Cvia f2py
1.2
Cvia Cython
1.2
vectorized Python, version 1
1.9
Cython random.randint
33.6
plain Python
37.7
vectorized Python, version 2
105.0
The CPU time of the plain Python version was 10 s, which is reasonably
fast for obtaining a fairly accurate result in this problem. The lesson
learned is therefore that a Monte Carlo simulation can be implemented
in plain Python first. If more speed is needed, one can just add type
information and create a Cython code. StudyingtheHTML file with what
Cython manages to translate to C may give hints about how successful
the Cython code is and point to optimizations, like avoiding the call to
random.randint inthepresentcase.OptimalCythoncoderunshere
at approximately the same speed as calling a handwritten C function
with the time-consuming loops. It is to be noticed that the stand-alone
Cprogram here ran faster than calling C from Python, probably because
the amount of calculations is not large enough to make the overhead of
calling C negligible.
Vectorized Python do give a great speed-up compared to plain loops
in Python, if done correctly, but the efficiency is not on par with Cython
or handwritten C. Even more important is the fact that vectorized code
is not at all as readable as the algorithm expressed in plain Python,
Cython, or C. Cython therefore provides a very attractive combination
of readability, ease of programming, and high speed.
Documents you may be interested
Documents you may be interested