File: lapack.py

package info (click to toggle)
python-scipy 0.7.2%2Bdfsg1-1%2Bdeb6u1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze-lts
  • size: 28,572 kB
  • ctags: 36,183
  • sloc: cpp: 216,880; fortran: 76,016; python: 71,833; ansic: 62,118; makefile: 243; sh: 17
file content (116 lines) | stat: -rw-r--r-- 3,826 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
## Automatically adapted for scipy Oct 18, 2005 by

#
# Author: Pearu Peterson, March 2002
#

__all__ = ['get_lapack_funcs']

import new

# The following ensures that possibly missing flavor (C or Fortran) is
# replaced with the available one. If none is available, exception
# is raised at the first attempt to use the resources.

import numpy

from scipy.linalg import flapack
from scipy.linalg import clapack
_use_force_clapack = 1
if hasattr(clapack,'empty_module'):
    clapack = flapack
    _use_force_clapack = 0
elif hasattr(flapack,'empty_module'):
    flapack = clapack

def cast_to_lapack_prefix(t):
    if issubclass(t, numpy.single):
        prefix = 's'
    elif issubclass(t, numpy.double):
        prefix = 'd'
    elif issubclass(t, numpy.longdouble):
        prefix = 'd'
    elif issubclass(t, numpy.csingle):
        prefix = 'c'
    elif issubclass(t, numpy.cdouble):
        prefix = 'z'
    elif issubclass(t, numpy.clongdouble):
        prefix = 'z'
    else:
        prefix = 'd'
    return prefix

prefix_to_order = dict(s=3, d=2, c=1, z=0)
order_to_prefix = ['s', 'd', 'c', 'z']
prefix_to_dtype = dict(s=numpy.single, d=numpy.double,
                       c=numpy.csingle, z=numpy.cdouble)

def find_best_lapack_type(arrays):
    if not arrays:
        return 'd', numpy.double, False
    ordering = []
    for i in range(len(arrays)):
        t = arrays[i].dtype.type
        prefix = cast_to_lapack_prefix(t)
        order = prefix_to_order[prefix]
        ordering.append((order, prefix, i))
    ordering.sort()
    _, required_prefix, lowest_array_index = ordering[0]
    dtype = prefix_to_dtype[required_prefix]
    isfortran = numpy.isfortran(arrays[lowest_array_index])
    return required_prefix, dtype, isfortran

def get_lapack_funcs(names, arrays=()):
    """Return available LAPACK function objects with names.
    arrays are used to determine the optimal prefix of
    LAPACK routines.
    """
    #If force_clapack is True then available Atlas routine
    #is returned for column major storaged arrays with
    #rowmajor argument set to False.
    force_clapack=False  #XXX: Don't set it true! The feature is unreliable
                         #     and may cause incorrect results.
                         #     See test_basic.test_solve.check_20Feb04_bug.

    required_prefix, dtype, isfortran = find_best_lapack_type(arrays)
    # Default lookup:
    if isfortran:
        # prefer Fortran code for leading array with column major order
        m1, m2 = flapack, clapack
    else:
        # in all other cases, C code is preferred
        m1, m2 = clapack, flapack
    if not _use_force_clapack:
        force_clapack = False
    funcs = []
    m1_name = m1.__name__.split('.')[-1]
    m2_name = m2.__name__.split('.')[-1]
    for name in names:
        func_name = required_prefix + name
        func = getattr(m1,func_name,None)
        if func is None:
            func = getattr(m2,func_name)
            func.module_name = m2_name
        else:
            func.module_name = m1_name
            if force_clapack and m1 is flapack:
                func2 = getattr(m2,func_name,None)
                if func2 is not None:
                    exec _colmajor_func_template % {'func_name':func_name}
                    func = new.function(func_code,
                                        {'clapack_func':func2},
                                        func_name)
                    func.module_name = m2_name
                    func.__doc__ = func2.__doc__
        func.prefix = required_prefix
        func.dtype = dtype
        funcs.append(func)
    return tuple(funcs)

_colmajor_func_template = '''\
def %(func_name)s(*args,**kws):
    if "rowmajor" not in kws:
        kws["rowmajor"] = 0
    return clapack_func(*args,**kws)
func_code = %(func_name)s.func_code
'''