.\numpy\numpy\linalg\lapack_lite\fortran.py
# WARNING! This a Python 2 script. Read README.rst for rationale.
# 引入 re 和 itertools 模块
import re
import itertools
# 检查给定行是否为空白行
def isBlank(line):
return not line
# 检查给定行是否是标签行(以数字开头)
def isLabel(line):
return line[0].isdigit()
# 检查给定行是否是注释行(不以空格开头)
def isComment(line):
return line[0] != ' '
# 检查给定行是否是续行(第 6 个字符不是空格)
def isContinuation(line):
return line[5] != ' '
# 定义常量 COMMENT, STATEMENT, CONTINUATION 用于表示不同类型的行
COMMENT, STATEMENT, CONTINUATION = 0, 1, 2
# 函数:确定 Fortran 代码行的类型
def lineType(line):
"""Return the type of a line of Fortran code."""
if isBlank(line):
return COMMENT
elif isLabel(line):
return STATEMENT
elif isComment(line):
return COMMENT
elif isContinuation(line):
return CONTINUATION
else:
return STATEMENT
# 类:LineIterator,用于迭代处理行并去除行尾空格
class LineIterator:
"""LineIterator(iterable)
Return rstrip()'d lines from iterable, while keeping a count of the
line number in the .lineno attribute.
"""
def __init__(self, iterable):
object.__init__(self)
self.iterable = iter(iterable)
self.lineno = 0
def __iter__(self):
return self
def __next__(self):
self.lineno += 1
line = next(self.iterable)
line = line.rstrip()
return line
next = __next__
# 类:PushbackIterator,支持将元素推回迭代器
class PushbackIterator:
"""PushbackIterator(iterable)
Return an iterator for which items can be pushed back into.
Call the .pushback(item) method to have item returned as the next
value of next().
"""
def __init__(self, iterable):
object.__init__(self)
self.iterable = iter(iterable)
self.buffer = []
def __iter__(self):
return self
def __next__(self):
if self.buffer:
return self.buffer.pop()
else:
return next(self.iterable)
def pushback(self, item):
self.buffer.append(item)
next = __next__
# 函数:fortranSourceLines,返回一个迭代器,处理 Fortran 源文件的语句行
def fortranSourceLines(fo):
"""Return an iterator over statement lines of a Fortran source file.
Comment and blank lines are stripped out, and continuation lines are
merged.
"""
numberingiter = LineIterator(fo)
# 在末尾添加一个额外的空字符串,以处理续行
with_extra = itertools.chain(numberingiter, [''])
pushbackiter = PushbackIterator(with_extra)
for line in pushbackiter:
t = lineType(line)
if t == COMMENT:
continue
elif t == STATEMENT:
lines = [line]
# 处理续行的逻辑,保证行的连续性
for next_line in pushbackiter:
t = lineType(next_line)
if t == CONTINUATION:
lines.append(next_line[6:])
else:
pushbackiter.pushback(next_line)
break
yield numberingiter.lineno, ''.join(lines)
else:
raise ValueError("jammed: continuation line not expected: %s:%d" %
(fo.name, numberingiter.lineno))
# 函数:getDependencies(filename)
def getDependencies(filename):
"""
对于一个 Fortran 源文件,返回其中声明为 EXTERNAL 的例程列表。
"""
# 编译正则表达式模式,用于匹配以 EXTERNAL 开头的行(忽略大小写)
external_pat = re.compile(r'^\s*EXTERNAL\s', re.I)
# 初始化例程列表
routines = []
# 打开文件并进行迭代处理每一行
with open(filename) as fo:
# 使用自定义的函数迭代处理 Fortran 源文件的行
for lineno, line in fortranSourceLines(fo):
# 尝试在当前行中匹配 EXTERNAL 的模式
m = external_pat.match(line)
if m:
# 如果匹配成功,提取 EXTERNAL 后面的例程名称列表
names = line[m.end():].strip().split(',')
# 去除每个名称的首尾空白字符并转换为小写
names = [n.strip().lower() for n in names]
# 过滤掉空的名称
names = [n for n in names if n]
# 将提取的例程名称列表添加到总例程列表中
routines.extend(names)
# 返回最终的例程名称列表作为结果
return routines
.\numpy\numpy\linalg\lapack_lite\lapack_lite_names.h
/*
* NOTE: This is generated code. Look in numpy/linalg/lapack_lite for
* information on remaking this file.
*/
/*
* This file renames all BLAS/LAPACK and f2c symbols to avoid
* dynamic symbol name conflicts, in cases where e.g.
* integer sizes do not match with 'standard' ABI.
*/
// 定义了一系列宏,用于重命名 BLAS/LAPACK 和 f2c 符号,避免动态符号名称冲突
#define caxpy_ BLAS_FUNC(caxpy)
#define ccopy_ BLAS_FUNC(ccopy)
#define cdotc_ BLAS_FUNC(cdotc)
#define cdotu_ BLAS_FUNC(cdotu)
#define cgebak_ BLAS_FUNC(cgebak)
#define cgebal_ BLAS_FUNC(cgebal)
#define cgebd2_ BLAS_FUNC(cgebd2)
#define cgebrd_ BLAS_FUNC(cgebrd)
#define cgeev_ BLAS_FUNC(cgeev)
#define cgehd2_ BLAS_FUNC(cgehd2)
#define cgehrd_ BLAS_FUNC(cgehrd)
#define cgelq2_ BLAS_FUNC(cgelq2)
#define cgelqf_ BLAS_FUNC(cgelqf)
#define cgelsd_ BLAS_FUNC(cgelsd)
#define cgemm_ BLAS_FUNC(cgemm)
#define cgemv_ BLAS_FUNC(cgemv)
#define cgeqr2_ BLAS_FUNC(cgeqr2)
#define cgeqrf_ BLAS_FUNC(cgeqrf)
#define cgerc_ BLAS_FUNC(cgerc)
#define cgeru_ BLAS_FUNC(cgeru)
#define cgesdd_ BLAS_FUNC(cgesdd)
#define cgesv_ BLAS_FUNC(cgesv)
#define cgetf2_ BLAS_FUNC(cgetf2)
#define cgetrf_ BLAS_FUNC(cgetrf)
#define cgetrs_ BLAS_FUNC(cgetrs)
#define cheevd_ BLAS_FUNC(cheevd)
#define chemv_ BLAS_FUNC(chemv)
#define cher2_ BLAS_FUNC(cher2)
#define cher2k_ BLAS_FUNC(cher2k)
#define cherk_ BLAS_FUNC(cherk)
#define chetd2_ BLAS_FUNC(chetd2)
#define chetrd_ BLAS_FUNC(chetrd)
#define chseqr_ BLAS_FUNC(chseqr)
#define clabrd_ BLAS_FUNC(clabrd)
#define clacgv_ BLAS_FUNC(clacgv)
#define clacp2_ BLAS_FUNC(clacp2)
#define clacpy_ BLAS_FUNC(clacpy)
#define clacrm_ BLAS_FUNC(clacrm)
#define cladiv_ BLAS_FUNC(cladiv)
#define claed0_ BLAS_FUNC(claed0)
#define claed7_ BLAS_FUNC(claed7)
#define claed8_ BLAS_FUNC(claed8)
#define clahqr_ BLAS_FUNC(clahqr)
#define clahr2_ BLAS_FUNC(clahr2)
#define clals0_ BLAS_FUNC(clals0)
#define clalsa_ BLAS_FUNC(clalsa)
#define clalsd_ BLAS_FUNC(clalsd)
#define clange_ BLAS_FUNC(clange)
#define clanhe_ BLAS_FUNC(clanhe)
#define claqr0_ BLAS_FUNC(claqr0)
#define claqr1_ BLAS_FUNC(claqr1)
#define claqr2_ BLAS_FUNC(claqr2)
#define claqr3_ BLAS_FUNC(claqr3)
#define claqr4_ BLAS_FUNC(claqr4)
#define claqr5_ BLAS_FUNC(claqr5)
#define clarcm_ BLAS_FUNC(clarcm)
#define clarf_ BLAS_FUNC(clarf)
#define clarfb_ BLAS_FUNC(clarfb)
#define clarfg_ BLAS_FUNC(clarfg)
#define clarft_ BLAS_FUNC(clarft)
#define clartg_ BLAS_FUNC(clartg)
#define clascl_ BLAS_FUNC(clascl)
#define claset_ BLAS_FUNC(claset)
#define clasr_ BLAS_FUNC(clasr)
#define classq_ BLAS_FUNC(classq)
#define claswp_ BLAS_FUNC(claswp)
#define clatrd_ BLAS_FUNC(clatrd)
#define clatrs_ BLAS_FUNC(clatrs)
#define clauu2_ BLAS_FUNC(clauu2)
#define clauum_ BLAS_FUNC(clauum)
#define cpotf2_ BLAS_FUNC(cpotf2)
#define cpotrf_ BLAS_FUNC(cpotrf)
#define cpotri_ BLAS_FUNC(cpotri)
#define cpotrs_ BLAS_FUNC(cpotrs)
#define crot_ BLAS_FUNC(crot)
#define cscal_ BLAS_FUNC(cscal)
#define csrot_ BLAS_FUNC(csrot)
#define csscal_ BLAS_FUNC(csscal)
#define cstedc_ BLAS_FUNC(cstedc)
#define csteqr_ BLAS_FUNC(csteqr)
// 定义宏,将函数名映射到 BLAS_FUNC 宏定义的函数名
#define cswap_ BLAS_FUNC(cswap)
#define ctrevc_ BLAS_FUNC(ctrevc)
#define ctrexc_ BLAS_FUNC(ctrexc)
#define ctrmm_ BLAS_FUNC(ctrmm)
#define ctrmv_ BLAS_FUNC(ctrmv)
#define ctrsm_ BLAS_FUNC(ctrsm)
#define ctrsv_ BLAS_FUNC(ctrsv)
#define ctrti2_ BLAS_FUNC(ctrti2)
#define ctrtri_ BLAS_FUNC(ctrtri)
#define cung2r_ BLAS_FUNC(cung2r)
#define cungbr_ BLAS_FUNC(cungbr)
#define cunghr_ BLAS_FUNC(cunghr)
#define cungl2_ BLAS_FUNC(cungl2)
#define cunglq_ BLAS_FUNC(cunglq)
#define cungqr_ BLAS_FUNC(cungqr)
#define cunm2l_ BLAS_FUNC(cunm2l)
#define cunm2r_ BLAS_FUNC(cunm2r)
#define cunmbr_ BLAS_FUNC(cunmbr)
#define cunmhr_ BLAS_FUNC(cunmhr)
#define cunml2_ BLAS_FUNC(cunml2)
#define cunmlq_ BLAS_FUNC(cunmlq)
#define cunmql_ BLAS_FUNC(cunmql)
#define cunmqr_ BLAS_FUNC(cunmqr)
#define cunmtr_ BLAS_FUNC(cunmtr)
#define daxpy_ BLAS_FUNC(daxpy)
#define dbdsdc_ BLAS_FUNC(dbdsdc)
#define dbdsqr_ BLAS_FUNC(dbdsqr)
#define dcabs1_ BLAS_FUNC(dcabs1)
#define dcopy_ BLAS_FUNC(dcopy)
#define ddot_ BLAS_FUNC(ddot)
#define dgebak_ BLAS_FUNC(dgebak)
#define dgebal_ BLAS_FUNC(dgebal)
#define dgebd2_ BLAS_FUNC(dgebd2)
#define dgebrd_ BLAS_FUNC(dgebrd)
#define dgeev_ BLAS_FUNC(dgeev)
#define dgehd2_ BLAS_FUNC(dgehd2)
#define dgehrd_ BLAS_FUNC(dgehrd)
#define dgelq2_ BLAS_FUNC(dgelq2)
#define dgelqf_ BLAS_FUNC(dgelqf)
#define dgelsd_ BLAS_FUNC(dgelsd)
#define dgemm_ BLAS_FUNC(dgemm)
#define dgemv_ BLAS_FUNC(dgemv)
#define dgeqr2_ BLAS_FUNC(dgeqr2)
#define dgeqrf_ BLAS_FUNC(dgeqrf)
#define dger_ BLAS_FUNC(dger)
#define dgesdd_ BLAS_FUNC(dgesdd)
#define dgesv_ BLAS_FUNC(dgesv)
#define dgetf2_ BLAS_FUNC(dgetf2)
#define dgetrf_ BLAS_FUNC(dgetrf)
#define dgetrs_ BLAS_FUNC(dgetrs)
#define dhseqr_ BLAS_FUNC(dhseqr)
#define disnan_ BLAS_FUNC(disnan)
#define dlabad_ BLAS_FUNC(dlabad)
#define dlabrd_ BLAS_FUNC(dlabrd)
#define dlacpy_ BLAS_FUNC(dlacpy)
#define dladiv_ BLAS_FUNC(dladiv)
#define dlae2_ BLAS_FUNC(dlae2)
#define dlaed0_ BLAS_FUNC(dlaed0)
#define dlaed1_ BLAS_FUNC(dlaed1)
#define dlaed2_ BLAS_FUNC(dlaed2)
#define dlaed3_ BLAS_FUNC(dlaed3)
#define dlaed4_ BLAS_FUNC(dlaed4)
#define dlaed5_ BLAS_FUNC(dlaed5)
#define dlaed6_ BLAS_FUNC(dlaed6)
#define dlaed7_ BLAS_FUNC(dlaed7)
#define dlaed8_ BLAS_FUNC(dlaed8)
#define dlaed9_ BLAS_FUNC(dlaed9)
#define dlaeda_ BLAS_FUNC(dlaeda)
#define dlaev2_ BLAS_FUNC(dlaev2)
#define dlaexc_ BLAS_FUNC(dlaexc)
#define dlahqr_ BLAS_FUNC(dlahqr)
#define dlahr2_ BLAS_FUNC(dlahr2)
#define dlaisnan_ BLAS_FUNC(dlaisnan)
#define dlaln2_ BLAS_FUNC(dlaln2)
#define dlals0_ BLAS_FUNC(dlals0)
#define dlalsa_ BLAS_FUNC(dlalsa)
#define dlalsd_ BLAS_FUNC(dlalsd)
#define dlamc1_ BLAS_FUNC(dlamc1)
#define dlamc2_ BLAS_FUNC(dlamc2)
#define dlamc3_ BLAS_FUNC(dlamc3)
#define dlamc4_ BLAS_FUNC(dlamc4)
#define dlamc5_ BLAS_FUNC(dlamc5)
#define dlamch_ BLAS_FUNC(dlamch)
#define dlamrg_ BLAS_FUNC(dlamrg)
#define dlange_ BLAS_FUNC(dlange)
#define dlanst_ BLAS_FUNC(dlanst)
#define dlansy_ BLAS_FUNC(dlansy)
#define dlanv2_ BLAS_FUNC(dlanv2)
#define dlapy2_ BLAS_FUNC(dlapy2)
// 定义各个 BLAS 函数的宏,它们是对应于 LAPACK 和 BLAS 数学库中特定函数的符号名称映射
#define dlapy3_ BLAS_FUNC(dlapy3)
#define dlaqr0_ BLAS_FUNC(dlaqr0)
#define dlaqr1_ BLAS_FUNC(dlaqr1)
#define dlaqr2_ BLAS_FUNC(dlaqr2)
#define dlaqr3_ BLAS_FUNC(dlaqr3)
#define dlaqr4_ BLAS_FUNC(dlaqr4)
#define dlaqr5_ BLAS_FUNC(dlaqr5)
#define dlarf_ BLAS_FUNC(dlarf)
#define dlarfb_ BLAS_FUNC(dlarfb)
#define dlarfg_ BLAS_FUNC(dlarfg)
#define dlarft_ BLAS_FUNC(dlarft)
#define dlarfx_ BLAS_FUNC(dlarfx)
#define dlartg_ BLAS_FUNC(dlartg)
#define dlas2_ BLAS_FUNC(dlas2)
#define dlascl_ BLAS_FUNC(dlascl)
#define dlasd0_ BLAS_FUNC(dlasd0)
#define dlasd1_ BLAS_FUNC(dlasd1)
#define dlasd2_ BLAS_FUNC(dlasd2)
#define dlasd3_ BLAS_FUNC(dlasd3)
#define dlasd4_ BLAS_FUNC(dlasd4)
#define dlasd5_ BLAS_FUNC(dlasd5)
#define dlasd6_ BLAS_FUNC(dlasd6)
#define dlasd7_ BLAS_FUNC(dlasd7)
#define dlasd8_ BLAS_FUNC(dlasd8)
#define dlasda_ BLAS_FUNC(dlasda)
#define dlasdq_ BLAS_FUNC(dlasdq)
#define dlasdt_ BLAS_FUNC(dlasdt)
#define dlaset_ BLAS_FUNC(dlaset)
#define dlasq1_ BLAS_FUNC(dlasq1)
#define dlasq2_ BLAS_FUNC(dlasq2)
#define dlasq3_ BLAS_FUNC(dlasq3)
#define dlasq4_ BLAS_FUNC(dlasq4)
#define dlasq5_ BLAS_FUNC(dlasq5)
#define dlasq6_ BLAS_FUNC(dlasq6)
#define dlasr_ BLAS_FUNC(dlasr)
#define dlasrt_ BLAS_FUNC(dlasrt)
#define dlassq_ BLAS_FUNC(dlassq)
#define dlasv2_ BLAS_FUNC(dlasv2)
#define dlaswp_ BLAS_FUNC(dlaswp)
#define dlasy2_ BLAS_FUNC(dlasy2)
#define dlatrd_ BLAS_FUNC(dlatrd)
#define dlauu2_ BLAS_FUNC(dlauu2)
#define dlauum_ BLAS_FUNC(dlauum)
#define dnrm2_ BLAS_FUNC(dnrm2)
#define dorg2r_ BLAS_FUNC(dorg2r)
#define dorgbr_ BLAS_FUNC(dorgbr)
#define dorghr_ BLAS_FUNC(dorghr)
#define dorgl2_ BLAS_FUNC(dorgl2)
#define dorglq_ BLAS_FUNC(dorglq)
#define dorgqr_ BLAS_FUNC(dorgqr)
#define dorm2l_ BLAS_FUNC(dorm2l)
#define dorm2r_ BLAS_FUNC(dorm2r)
#define dormbr_ BLAS_FUNC(dormbr)
#define dormhr_ BLAS_FUNC(dormhr)
#define dorml2_ BLAS_FUNC(dorml2)
#define dormlq_ BLAS_FUNC(dormlq)
#define dormql_ BLAS_FUNC(dormql)
#define dormqr_ BLAS_FUNC(dormqr)
#define dormtr_ BLAS_FUNC(dormtr)
#define dpotf2_ BLAS_FUNC(dpotf2)
#define dpotrf_ BLAS_FUNC(dpotrf)
#define dpotri_ BLAS_FUNC(dpotri)
#define dpotrs_ BLAS_FUNC(dpotrs)
#define drot_ BLAS_FUNC(drot)
#define dscal_ BLAS_FUNC(dscal)
#define dstedc_ BLAS_FUNC(dstedc)
#define dsteqr_ BLAS_FUNC(dsteqr)
#define dsterf_ BLAS_FUNC(dsterf)
#define dswap_ BLAS_FUNC(dswap)
#define dsyevd_ BLAS_FUNC(dsyevd)
#define dsymv_ BLAS_FUNC(dsymv)
#define dsyr2_ BLAS_FUNC(dsyr2)
#define dsyr2k_ BLAS_FUNC(dsyr2k)
#define dsyrk_ BLAS_FUNC(dsyrk)
#define dsytd2_ BLAS_FUNC(dsytd2)
#define dsytrd_ BLAS_FUNC(dsytrd)
#define dtrevc_ BLAS_FUNC(dtrevc)
#define dtrexc_ BLAS_FUNC(dtrexc)
#define dtrmm_ BLAS_FUNC(dtrmm)
#define dtrmv_ BLAS_FUNC(dtrmv)
#define dtrsm_ BLAS_FUNC(dtrsm)
#define dtrti2_ BLAS_FUNC(dtrti2)
#define dtrtri_ BLAS_FUNC(dtrtri)
#define dzasum_ BLAS_FUNC(dzasum)
#define dznrm2_ BLAS_FUNC(dznrm2)
#define icamax_ BLAS_FUNC(icamax)
#define idamax_ BLAS_FUNC(idamax)
#define ieeeck_ BLAS_FUNC(ieeeck)
#define ilaclc_ BLAS_FUNC(ilaclc)
#define ilaclr_ BLAS_FUNC(ilaclr)
// 定义宏 ilaclr_,展开为 BLAS_FUNC(ilaclr) 的内容
#define iladlc_ BLAS_FUNC(iladlc)
// 定义宏 iladlc_,展开为 BLAS_FUNC(iladlc) 的内容
#define iladlr_ BLAS_FUNC(iladlr)
// 定义宏 iladlr_,展开为 BLAS_FUNC(iladlr) 的内容
#define ilaenv_ BLAS_FUNC(ilaenv)
// 定义宏 ilaenv_,展开为 BLAS_FUNC(ilaenv) 的内容
#define ilaslc_ BLAS_FUNC(ilaslc)
// 定义宏 ilaslc_,展开为 BLAS_FUNC(ilaslc) 的内容
#define ilaslr_ BLAS_FUNC(ilaslr)
// 定义宏 ilaslr_,展开为 BLAS_FUNC(ilaslr) 的内容
#define ilazlc_ BLAS_FUNC(ilazlc)
// 定义宏 ilazlc_,展开为 BLAS_FUNC(ilazlc) 的内容
#define ilazlr_ BLAS_FUNC(ilazlr)
// 定义宏 ilazlr_,展开为 BLAS_FUNC(ilazlr) 的内容
#define iparmq_ BLAS_FUNC(iparmq)
// 定义宏 iparmq_,展开为 BLAS_FUNC(iparmq) 的内容
#define isamax_ BLAS_FUNC(isamax)
// 定义宏 isamax_,展开为 BLAS_FUNC(isamax) 的内容
#define izamax_ BLAS_FUNC(izamax)
// 定义宏 izamax_,展开为 BLAS_FUNC(izamax) 的内容
#define lsame_ BLAS_FUNC(lsame)
// 定义宏 lsame_,展开为 BLAS_FUNC(lsame) 的内容
#define saxpy_ BLAS_FUNC(saxpy)
// 定义宏 saxpy_,展开为 BLAS_FUNC(saxpy) 的内容
#define sbdsdc_ BLAS_FUNC(sbdsdc)
// 定义宏 sbdsdc_,展开为 BLAS_FUNC(sbdsdc) 的内容
#define sbdsqr_ BLAS_FUNC(sbdsqr)
// 定义宏 sbdsqr_,展开为 BLAS_FUNC(sbdsqr) 的内容
#define scabs1_ BLAS_FUNC(scabs1)
// 定义宏 scabs1_,展开为 BLAS_FUNC(scabs1) 的内容
#define scasum_ BLAS_FUNC(scasum)
// 定义宏 scasum_,展开为 BLAS_FUNC(scasum) 的内容
#define scnrm2_ BLAS_FUNC(scnrm2)
// 定义宏 scnrm2_,展开为 BLAS_FUNC(scnrm2) 的内容
#define scopy_ BLAS_FUNC(scopy)
// 定义宏 scopy_,展开为 BLAS_FUNC(scopy) 的内容
#define sdot_ BLAS_FUNC(sdot)
// 定义宏 sdot_,展开为 BLAS_FUNC(sdot) 的内容
#define sgebak_ BLAS_FUNC(sgebak)
// 定义宏 sgebak_,展开为 BLAS_FUNC(sgebak) 的内容
#define sgebal_ BLAS_FUNC(sgebal)
// 定义宏 sgebal_,展开为 BLAS_FUNC(sgebal) 的内容
#define sgebd2_ BLAS_FUNC(sgebd2)
// 定义宏 sgebd2_,展开为 BLAS_FUNC(sgebd2) 的内容
#define sgebrd_ BLAS_FUNC(sgebrd)
// 定义宏 sgebrd_,展开为 BLAS_FUNC(sgebrd) 的内容
#define sgeev_ BLAS_FUNC(sgeev)
// 定义宏 sgeev_,展开为 BLAS_FUNC(sgeev) 的内容
#define sgehd2_ BLAS_FUNC(sgehd2)
// 定义宏 sgehd2_,展开为 BLAS_FUNC(sgehd2) 的内容
#define sgehrd_ BLAS_FUNC(sgehrd)
// 定义宏 sgehrd_,展开为 BLAS_FUNC(sgehrd) 的内容
#define sgelq2_ BLAS_FUNC(sgelq2)
// 定义宏 sgelq2_,展开为 BLAS_FUNC(sgelq2) 的内容
#define sgelqf_ BLAS_FUNC(sgelqf)
// 定义宏 sgelqf_,展开为 BLAS_FUNC(sgelqf) 的内容
#define sgelsd_ BLAS_FUNC(sgelsd)
// 定义宏 sgelsd_,展开为 BLAS_FUNC(sgelsd) 的内容
#define sgemm_ BLAS_FUNC(sgemm)
// 定义宏 sgemm_,展开为 BLAS_FUNC(sgemm) 的内容
#define sgemv_ BLAS_FUNC(sgemv)
// 定义宏 sgemv_,展开为 BLAS_FUNC(sgemv) 的内容
#define sgeqr2_ BLAS_FUNC(sgeqr2)
// 定义宏 sgeqr2_,展开为 BLAS_FUNC(sgeqr2) 的内容
#define sgeqrf_ BLAS_FUNC(sgeqrf)
// 定义宏 sgeqrf_,展开为 BLAS_FUNC(sgeqrf) 的内容
#define sger_ BLAS_FUNC(sger)
// 定义宏 sger_,展开为 BLAS_FUNC(sger) 的内容
#define sgesdd_ BLAS_FUNC(sgesdd)
// 定义宏 sgesdd_,展开为 BLAS_FUNC(sgesdd) 的内容
#define sgesv_ BLAS_FUNC(sgesv)
// 定义宏 sgesv_,展开为 BLAS_FUNC(sgesv) 的内容
#define sgetf2_ BLAS_FUNC(sgetf2)
// 定义宏 sgetf2_,展开为 BLAS_FUNC(sgetf2) 的内容
#define sgetrf_ BLAS_FUNC(sgetrf)
// 定义宏 sgetrf_,展开为 BLAS_FUNC(sgetrf) 的内容
#define sgetrs_ BLAS_FUNC(sgetrs)
// 定义宏 sgetrs_,展开为 BLAS_FUNC(sgetrs) 的内容
#define shseqr_ BLAS_FUNC(shseqr)
// 定义宏 shseqr_,展开为 BLAS_FUNC(shseqr) 的内容
#define sisnan_ BLAS_FUNC(sisnan)
// 定义宏 sisnan_,展开为 BLAS_FUNC(sisnan) 的内容
#define slabad_ BLAS_FUNC(slabad)
// 定义宏 slabad_,展开为 BLAS_FUNC(slabad) 的内容
#define slabrd_ BLAS_FUNC(slabrd)
// 定义宏 slabrd_,展开为 BLAS_FUNC(slabrd) 的内容
#define slacpy_ BLAS_FUNC(slacpy)
// 定义宏 slacpy_,展开为 BLAS_FUNC(slacpy) 的内容
#define sladiv_ BLAS_FUNC(sladiv)
// 定义宏 sladiv_,展开为 BLAS_FUNC(sladiv) 的内容
#define slae2_ BLAS_FUNC(slae2)
// 定义宏 slae2_,展开为 BLAS_FUNC(slae2) 的内容
#define slaed0_ BLAS_FUNC(slaed0)
// 定义宏 slaed0_,展开为 BLAS_FUNC(slaed0) 的内容
#define slaed1_ BLAS_FUNC(slaed1)
// 定义宏 slaed1_,展开为 BLAS_FUNC(slaed1) 的内容
#define slaed2_ BLAS_FUNC(slaed2)
// 定义宏 slaed2_,展开为 BLAS_FUNC(slaed2) 的内容
#define slaed3_ BLAS_FUNC(slaed3)
// 定义宏 slaed3_,展开为 BLAS_FUNC(slaed3) 的内容
#define slaed4_ BLAS_FUNC(slaed4)
// 定义宏 slaed4_,展开为 BLAS_FUNC(slaed4) 的内容
#define slaed5_ BLAS_FUNC(slaed5)
// 定义宏 slaed5_,展开为 BLAS_FUNC(slaed5) 的内容
#define slaed6_ BLAS_FUNC(slaed6)
// 定义宏 slaed6_,展开为 BLAS_FUNC(slaed6) 的内容
#define slaed7_ BLAS_FUNC(slaed7)
// 定义宏 slaed7_,展开为 BLAS_FUNC(slaed7) 的内容
#define slaed8_ BLAS_FUNC(slaed8)
// 定义宏 slaed8_,展开为 BLAS_FUNC(slaed8) 的内容
#define slaed
// 定义各个 BLAS 函数的别名,使用 BLAS_FUNC 宏进行定义
#define slarfg_ BLAS_FUNC(slarfg)
#define slarft_ BLAS_FUNC(slarft)
#define slarfx_ BLAS_FUNC(slarfx)
#define slartg_ BLAS_FUNC(slartg)
#define slas2_ BLAS_FUNC(slas2)
#define slascl_ BLAS_FUNC(slascl)
#define slasd0_ BLAS_FUNC(slasd0)
#define slasd1_ BLAS_FUNC(slasd1)
#define slasd2_ BLAS_FUNC(slasd2)
#define slasd3_ BLAS_FUNC(slasd3)
#define slasd4_ BLAS_FUNC(slasd4)
#define slasd5_ BLAS_FUNC(slasd5)
#define slasd6_ BLAS_FUNC(slasd6)
#define slasd7_ BLAS_FUNC(slasd7)
#define slasd8_ BLAS_FUNC(slasd8)
#define slasda_ BLAS_FUNC(slasda)
#define slasdq_ BLAS_FUNC(slasdq)
#define slasdt_ BLAS_FUNC(slasdt)
#define slaset_ BLAS_FUNC(slaset)
#define slasq1_ BLAS_FUNC(slasq1)
#define slasq2_ BLAS_FUNC(slasq2)
#define slasq3_ BLAS_FUNC(slasq3)
#define slasq4_ BLAS_FUNC(slasq4)
#define slasq5_ BLAS_FUNC(slasq5)
#define slasq6_ BLAS_FUNC(slasq6)
#define slasr_ BLAS_FUNC(slasr)
#define slasrt_ BLAS_FUNC(slasrt)
#define slassq_ BLAS_FUNC(slassq)
#define slasv2_ BLAS_FUNC(slasv2)
#define slaswp_ BLAS_FUNC(slaswp)
#define slasy2_ BLAS_FUNC(slasy2)
#define slatrd_ BLAS_FUNC(slatrd)
#define slauu2_ BLAS_FUNC(slauu2)
#define slauum_ BLAS_FUNC(slauum)
#define snrm2_ BLAS_FUNC(snrm2)
#define sorg2r_ BLAS_FUNC(sorg2r)
#define sorgbr_ BLAS_FUNC(sorgbr)
#define sorghr_ BLAS_FUNC(sorghr)
#define sorgl2_ BLAS_FUNC(sorgl2)
#define sorglq_ BLAS_FUNC(sorglq)
#define sorgqr_ BLAS_FUNC(sorgqr)
#define sorm2l_ BLAS_FUNC(sorm2l)
#define sorm2r_ BLAS_FUNC(sorm2r)
#define sormbr_ BLAS_FUNC(sormbr)
#define sormhr_ BLAS_FUNC(sormhr)
#define sorml2_ BLAS_FUNC(sorml2)
#define sormlq_ BLAS_FUNC(sormlq)
#define sormql_ BLAS_FUNC(sormql)
#define sormqr_ BLAS_FUNC(sormqr)
#define sormtr_ BLAS_FUNC(sormtr)
#define spotf2_ BLAS_FUNC(spotf2)
#define spotrf_ BLAS_FUNC(spotrf)
#define spotri_ BLAS_FUNC(spotri)
#define spotrs_ BLAS_FUNC(spotrs)
#define srot_ BLAS_FUNC(srot)
#define sscal_ BLAS_FUNC(sscal)
#define sstedc_ BLAS_FUNC(sstedc)
#define ssteqr_ BLAS_FUNC(ssteqr)
#define ssterf_ BLAS_FUNC(ssterf)
#define sswap_ BLAS_FUNC(sswap)
#define ssyevd_ BLAS_FUNC(ssyevd)
#define ssymv_ BLAS_FUNC(ssymv)
#define ssyr2_ BLAS_FUNC(ssyr2)
#define ssyr2k_ BLAS_FUNC(ssyr2k)
#define ssyrk_ BLAS_FUNC(ssyrk)
#define ssytd2_ BLAS_FUNC(ssytd2)
#define ssytrd_ BLAS_FUNC(ssytrd)
#define strevc_ BLAS_FUNC(strevc)
#define strexc_ BLAS_FUNC(strexc)
#define strmm_ BLAS_FUNC(strmm)
#define strmv_ BLAS_FUNC(strmv)
#define strsm_ BLAS_FUNC(strsm)
#define strti2_ BLAS_FUNC(strti2)
#define strtri_ BLAS_FUNC(strtri)
#define xerbla_ BLAS_FUNC(xerbla)
#define zaxpy_ BLAS_FUNC(zaxpy)
#define zcopy_ BLAS_FUNC(zcopy)
#define zdotc_ BLAS_FUNC(zdotc)
#define zdotu_ BLAS_FUNC(zdotu)
#define zdrot_ BLAS_FUNC(zdrot)
#define zdscal_ BLAS_FUNC(zdscal)
#define zgebak_ BLAS_FUNC(zgebak)
#define zgebal_ BLAS_FUNC(zgebal)
#define zgebd2_ BLAS_FUNC(zgebd2)
#define zgebrd_ BLAS_FUNC(zgebrd)
#define zgeev_ BLAS_FUNC(zgeev)
#define zgehd2_ BLAS_FUNC(zgehd2)
#define zgehrd_ BLAS_FUNC(zgehrd)
#define zgelq2_ BLAS_FUNC(zgelq2)
// 定义宏,用于重命名 BLAS 函数名,以下是一系列宏定义
#define zgelqf_ BLAS_FUNC(zgelqf)
#define zgelsd_ BLAS_FUNC(zgelsd)
#define zgemm_ BLAS_FUNC(zgemm)
#define zgemv_ BLAS_FUNC(zgemv)
#define zgeqr2_ BLAS_FUNC(zgeqr2)
#define zgeqrf_ BLAS_FUNC(zgeqrf)
#define zgerc_ BLAS_FUNC(zgerc)
#define zgeru_ BLAS_FUNC(zgeru)
#define zgesdd_ BLAS_FUNC(zgesdd)
#define zgesv_ BLAS_FUNC(zgesv)
#define zgetf2_ BLAS_FUNC(zgetf2)
#define zgetrf_ BLAS_FUNC(zgetrf)
#define zgetrs_ BLAS_FUNC(zgetrs)
#define zheevd_ BLAS_FUNC(zheevd)
#define zhemv_ BLAS_FUNC(zhemv)
#define zher2_ BLAS_FUNC(zher2)
#define zher2k_ BLAS_FUNC(zher2k)
#define zherk_ BLAS_FUNC(zherk)
#define zhetd2_ BLAS_FUNC(zhetd2)
#define zhetrd_ BLAS_FUNC(zhetrd)
#define zhseqr_ BLAS_FUNC(zhseqr)
#define zlabrd_ BLAS_FUNC(zlabrd)
#define zlacgv_ BLAS_FUNC(zlacgv)
#define zlacp2_ BLAS_FUNC(zlacp2)
#define zlacpy_ BLAS_FUNC(zlacpy)
#define zlacrm_ BLAS_FUNC(zlacrm)
#define zladiv_ BLAS_FUNC(zladiv)
#define zlaed0_ BLAS_FUNC(zlaed0)
#define zlaed7_ BLAS_FUNC(zlaed7)
#define zlaed8_ BLAS_FUNC(zlaed8)
#define zlahqr_ BLAS_FUNC(zlahqr)
#define zlahr2_ BLAS_FUNC(zlahr2)
#define zlals0_ BLAS_FUNC(zlals0)
#define zlalsa_ BLAS_FUNC(zlalsa)
#define zlalsd_ BLAS_FUNC(zlalsd)
#define zlange_ BLAS_FUNC(zlange)
#define zlanhe_ BLAS_FUNC(zlanhe)
#define zlaqr0_ BLAS_FUNC(zlaqr0)
#define zlaqr1_ BLAS_FUNC(zlaqr1)
#define zlaqr2_ BLAS_FUNC(zlaqr2)
#define zlaqr3_ BLAS_FUNC(zlaqr3)
#define zlaqr4_ BLAS_FUNC(zlaqr4)
#define zlaqr5_ BLAS_FUNC(zlaqr5)
#define zlarcm_ BLAS_FUNC(zlarcm)
#define zlarf_ BLAS_FUNC(zlarf)
#define zlarfb_ BLAS_FUNC(zlarfb)
#define zlarfg_ BLAS_FUNC(zlarfg)
#define zlarft_ BLAS_FUNC(zlarft)
#define zlartg_ BLAS_FUNC(zlartg)
#define zlascl_ BLAS_FUNC(zlascl)
#define zlaset_ BLAS_FUNC(zlaset)
#define zlasr_ BLAS_FUNC(zlasr)
#define zlassq_ BLAS_FUNC(zlassq)
#define zlaswp_ BLAS_FUNC(zlaswp)
#define zlatrd_ BLAS_FUNC(zlatrd)
#define zlatrs_ BLAS_FUNC(zlatrs)
#define zlauu2_ BLAS_FUNC(zlauu2)
#define zlauum_ BLAS_FUNC(zlauum)
#define zpotf2_ BLAS_FUNC(zpotf2)
#define zpotrf_ BLAS_FUNC(zpotrf)
#define zpotri_ BLAS_FUNC(zpotri)
#define zpotrs_ BLAS_FUNC(zpotrs)
#define zrot_ BLAS_FUNC(zrot)
#define zscal_ BLAS_FUNC(zscal)
#define zstedc_ BLAS_FUNC(zstedc)
#define zsteqr_ BLAS_FUNC(zsteqr)
#define zswap_ BLAS_FUNC(zswap)
#define ztrevc_ BLAS_FUNC(ztrevc)
#define ztrexc_ BLAS_FUNC(ztrexc)
#define ztrmm_ BLAS_FUNC(ztrmm)
#define ztrmv_ BLAS_FUNC(ztrmv)
#define ztrsm_ BLAS_FUNC(ztrsm)
#define ztrsv_ BLAS_FUNC(ztrsv)
#define ztrti2_ BLAS_FUNC(ztrti2)
#define ztrtri_ BLAS_FUNC(ztrtri)
#define zung2r_ BLAS_FUNC(zung2r)
#define zungbr_ BLAS_FUNC(zungbr)
#define zunghr_ BLAS_FUNC(zunghr)
#define zungl2_ BLAS_FUNC(zungl2)
#define zunglq_ BLAS_FUNC(zunglq)
#define zungqr_ BLAS_FUNC(zungqr)
#define zunm2l_ BLAS_FUNC(zunm2l)
#define zunm2r_ BLAS_FUNC(zunm2r)
#define zunmbr_ BLAS_FUNC(zunmbr)
#define zunmhr_ BLAS_FUNC(zunmhr)
#define zunml2_ BLAS_FUNC(zunml2)
#define zunmlq_ BLAS_FUNC(zunmlq)
#define zunmql_ BLAS_FUNC(zunmql)
#define zunmqr_ BLAS_FUNC(zunmqr)
# 定义 zunmtr_ 符号,表示 BLAS_FUNC 函数的 zunmtr 实现
#define zunmtr_ BLAS_FUNC(zunmtr)
# 下面是一系列由 f2c.c 导出的符号名称重定义,这些符号名称都指向 numpy_lapack_lite 模块中对应的函数或变量。
# 例如,将 abort_ 重定义为 numpy_lapack_lite_abort_
#define abort_ numpy_lapack_lite_abort_
#define c_abs numpy_lapack_lite_c_abs
#define c_cos numpy_lapack_lite_c_cos
#define c_div numpy_lapack_lite_c_div
#define c_exp numpy_lapack_lite_c_exp
#define c_log numpy_lapack_lite_c_log
#define c_sin numpy_lapack_lite_c_sin
#define c_sqrt numpy_lapack_lite_c_sqrt
#define d_abs numpy_lapack_lite_d_abs
#define d_acos numpy_lapack_lite_d_acos
#define d_asin numpy_lapack_lite_d_asin
#define d_atan numpy_lapack_lite_d_atan
#define d_atn2 numpy_lapack_lite_d_atn2
#define d_cnjg numpy_lapack_lite_d_cnjg
#define d_cos numpy_lapack_lite_d_cos
#define d_cosh numpy_lapack_lite_d_cosh
#define d_dim numpy_lapack_lite_d_dim
#define d_exp numpy_lapack_lite_d_exp
#define d_imag numpy_lapack_lite_d_imag
#define d_int numpy_lapack_lite_d_int
#define d_lg10 numpy_lapack_lite_d_lg10
#define d_log numpy_lapack_lite_d_log
#define d_mod numpy_lapack_lite_d_mod
#define d_nint numpy_lapack_lite_d_nint
#define d_prod numpy_lapack_lite_d_prod
#define d_sign numpy_lapack_lite_d_sign
#define d_sin numpy_lapack_lite_d_sin
#define d_sinh numpy_lapack_lite_d_sinh
#define d_sqrt numpy_lapack_lite_d_sqrt
#define d_tan numpy_lapack_lite_d_tan
#define d_tanh numpy_lapack_lite_d_tanh
#define derf_ numpy_lapack_lite_derf_
#define derfc_ numpy_lapack_lite_derfc_
#define do_fio numpy_lapack_lite_do_fio
#define do_lio numpy_lapack_lite_do_lio
#define do_uio numpy_lapack_lite_do_uio
#define e_rdfe numpy_lapack_lite_e_rdfe
#define e_rdue numpy_lapack_lite_e_rdue
#define e_rsfe numpy_lapack_lite_e_rsfe
#define e_rsfi numpy_lapack_lite_e_rsfi
#define e_rsle numpy_lapack_lite_e_rsle
#define e_rsli numpy_lapack_lite_e_rsli
#define e_rsue numpy_lapack_lite_e_rsue
#define e_wdfe numpy_lapack_lite_e_wdfe
#define e_wdue numpy_lapack_lite_e_wdue
#define e_wsfe numpy_lapack_lite_e_wsfe
#define e_wsfi numpy_lapack_lite_e_wsfi
#define e_wsle numpy_lapack_lite_e_wsle
#define e_wsli numpy_lapack_lite_e_wsli
#define e_wsue numpy_lapack_lite_e_wsue
#define ef1asc_ numpy_lapack_lite_ef1asc_
#define ef1cmc_ numpy_lapack_lite_ef1cmc_
#define erf_ numpy_lapack_lite_erf_
#define erfc_ numpy_lapack_lite_erfc_
#define f__cabs numpy_lapack_lite_f__cabs
#define f__cabsf numpy_lapack_lite_f__cabsf
#define f_back numpy_lapack_lite_f_back
#define f_clos numpy_lapack_lite_f_clos
#define f_end numpy_lapack_lite_f_end
#define f_exit numpy_lapack_lite_f_exit
#define f_inqu numpy_lapack_lite_f_inqu
#define f_open numpy_lapack_lite_f_open
#define f_rew numpy_lapack_lite_f_rew
#define flush_ numpy_lapack_lite_flush_
#define getarg_ numpy_lapack_lite_getarg_
#define getenv_ numpy_lapack_lite_getenv_
#define h_abs numpy_lapack_lite_h_abs
#define h_dim numpy_lapack_lite_h_dim
#define h_dnnt numpy_lapack_lite_h_dnnt
#define h_indx numpy_lapack_lite_h_indx
#define h_len numpy_lapack_lite_h_len
#define h_mod numpy_lapack_lite_h_mod
#define h_nint numpy_lapack_lite_h_nint
#define h_sign numpy_lapack_lite_h_sign
# 定义宏指令,用于将给定名称重新映射为对应的numpy_lapack_lite模块中的函数或变量
#define hl_ge numpy_lapack_lite_hl_ge
#define hl_gt numpy_lapack_lite_hl_gt
#define hl_le numpy_lapack_lite_hl_le
#define hl_lt numpy_lapack_lite_hl_lt
#define i_abs numpy_lapack_lite_i_abs
#define i_dim numpy_lapack_lite_i_dim
#define i_dnnt numpy_lapack_lite_i_dnnt
#define i_indx numpy_lapack_lite_i_indx
#define i_len numpy_lapack_lite_i_len
#define i_mod numpy_lapack_lite_i_mod
#define i_nint numpy_lapack_lite_i_nint
#define i_sign numpy_lapack_lite_i_sign
#define iargc_ numpy_lapack_lite_iargc_
#define l_ge numpy_lapack_lite_l_ge
#define l_gt numpy_lapack_lite_l_gt
#define l_le numpy_lapack_lite_l_le
#define l_lt numpy_lapack_lite_l_lt
#define pow_ci numpy_lapack_lite_pow_ci
#define pow_dd numpy_lapack_lite_pow_dd
#define pow_di numpy_lapack_lite_pow_di
#define pow_hh numpy_lapack_lite_pow_hh
#define pow_ii numpy_lapack_lite_pow_ii
#define pow_ri numpy_lapack_lite_pow_ri
#define pow_zi numpy_lapack_lite_pow_zi
#define pow_zz numpy_lapack_lite_pow_zz
#define r_abs numpy_lapack_lite_r_abs
#define r_acos numpy_lapack_lite_r_acos
#define r_asin numpy_lapack_lite_r_asin
#define r_atan numpy_lapack_lite_r_atan
#define r_atn2 numpy_lapack_lite_r_atn2
#define r_cnjg numpy_lapack_lite_r_cnjg
#define r_cos numpy_lapack_lite_r_cos
#define r_cosh numpy_lapack_lite_r_cosh
#define r_dim numpy_lapack_lite_r_dim
#define r_exp numpy_lapack_lite_r_exp
#define r_imag numpy_lapack_lite_r_imag
#define r_int numpy_lapack_lite_r_int
#define r_lg10 numpy_lapack_lite_r_lg10
#define r_log numpy_lapack_lite_r_log
#define r_mod numpy_lapack_lite_r_mod
#define r_nint numpy_lapack_lite_r_nint
#define r_sign numpy_lapack_lite_r_sign
#define r_sin numpy_lapack_lite_r_sin
#define r_sinh numpy_lapack_lite_r_sinh
#define r_sqrt numpy_lapack_lite_r_sqrt
#define r_tan numpy_lapack_lite_r_tan
#define r_tanh numpy_lapack_lite_r_tanh
#define s_cat numpy_lapack_lite_s_cat
#define s_cmp numpy_lapack_lite_s_cmp
#define s_copy numpy_lapack_lite_s_copy
#define s_paus numpy_lapack_lite_s_paus
#define s_rdfe numpy_lapack_lite_s_rdfe
#define s_rdue numpy_lapack_lite_s_rdue
#define s_rnge numpy_lapack_lite_s_rnge
#define s_rsfe numpy_lapack_lite_s_rsfe
#define s_rsfi numpy_lapack_lite_s_rsfi
#define s_rsle numpy_lapack_lite_s_rsle
#define s_rsli numpy_lapack_lite_s_rsli
#define s_rsne numpy_lapack_lite_s_rsne
#define s_rsni numpy_lapack_lite_s_rsni
#define s_rsue numpy_lapack_lite_s_rsue
#define s_stop numpy_lapack_lite_s_stop
#define s_wdfe numpy_lapack_lite_s_wdfe
#define s_wdue numpy_lapack_lite_s_wdue
#define s_wsfe numpy_lapack_lite_s_wsfe
#define s_wsfi numpy_lapack_lite_s_wsfi
#define s_wsle numpy_lapack_lite_s_wsle
#define s_wsli numpy_lapack_lite_s_wsli
#define s_wsne numpy_lapack_lite_s_wsne
#define s_wsni numpy_lapack_lite_s_wsni
#define s_wsue numpy_lapack_lite_s_wsue
#define sig_die numpy_lapack_lite_sig_die
#define signal_ numpy_lapack_lite_signal_
#define system_ numpy_lapack_lite_system_
#define z_abs numpy_lapack_lite_z_abs
#define z_cos numpy_lapack_lite_z_cos
# 定义五个宏,分别将其映射到 numpy_lapack_lite 库中的对应函数
#define z_div numpy_lapack_lite_z_div
#define z_exp numpy_lapack_lite_z_exp
#define z_log numpy_lapack_lite_z_log
#define z_sin numpy_lapack_lite_z_sin
#define z_sqrt numpy_lapack_lite_z_sqrt
.\numpy\numpy\linalg\lapack_lite\make_lite.py
#!/usr/bin/env python2.7
# WARNING! This a Python 2 script. Read README.rst for rationale.
"""
Usage: make_lite.py <wrapped_routines_file> <lapack_dir>
Typical invocation:
make_lite.py wrapped_routines /tmp/lapack-3.x.x
Requires the following to be on the path:
* f2c
* patch
"""
import sys # 导入 sys 模块,用于访问命令行参数和系统相关功能
import os # 导入 os 模块,提供了对操作系统进行调用的接口
import re # 导入 re 模块,用于处理正则表达式的匹配和操作
import subprocess # 导入 subprocess 模块,用于执行外部命令
import shutil # 导入 shutil 模块,提供了一些高级的文件操作功能
import fortran # 导入自定义的 fortran 模块,用于处理 Fortran 相关操作
import clapack_scrub # 导入自定义的 clapack_scrub 模块,用于处理 Clapack 相关操作
try:
from distutils.spawn import find_executable as which # 尝试从 distutils.spawn 模块导入 find_executable 函数(Python 2)
except ImportError:
from shutil import which # 如果导入失败,则从 shutil 模块导入 which 函数(Python 3)
# Arguments to pass to f2c. You'll always want -A for ANSI C prototypes
# Others of interest: -a to not make variables static by default
# -C to check array subscripts
F2C_ARGS = ['-A', '-Nx800'] # 设置传递给 f2c 的参数列表
# The header to add to the top of the f2c_*.c file. Note that dlamch_() calls
# will be replaced by the macros below by clapack_scrub.scrub_source()
HEADER_BLURB = '''\
/*
* NOTE: This is generated code. Look in numpy/linalg/lapack_lite for
* information on remaking this file.
*/
'''
HEADER = HEADER_BLURB + '''\
#include "f2c.h"
#ifdef HAVE_CONFIG
#include "config.h"
#else
extern doublereal dlamch_(char *);
#define EPSILON dlamch_("Epsilon")
#define SAFEMINIMUM dlamch_("Safe minimum")
#define PRECISION dlamch_("Precision")
#define BASE dlamch_("Base")
#endif
extern doublereal dlapy2_(doublereal *x, doublereal *y);
/*
f2c knows the exact rules for precedence, and so omits parentheses where not
strictly necessary. Since this is generated code, we don't really care if
it's readable, and we know what is written is correct. So don't warn about
them.
*/
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wparentheses"
#endif
'''
class FortranRoutine:
"""Wrapper for a Fortran routine in a file.
"""
type = 'generic'
def __init__(self, name=None, filename=None):
self.filename = filename
if name is None:
root, ext = os.path.splitext(filename)
name = root
self.name = name
self._dependencies = None
def dependencies(self):
if self._dependencies is None:
deps = fortran.getDependencies(self.filename)
self._dependencies = [d.lower() for d in deps]
return self._dependencies
def __repr__(self):
return "FortranRoutine({!r}, filename={!r})".format(self.name,
self.filename)
class UnknownFortranRoutine(FortranRoutine):
"""Wrapper for a Fortran routine for which the corresponding file
is not known.
"""
type = 'unknown'
def __init__(self, name):
FortranRoutine.__init__(self, name=name, filename='<unknown>')
def dependencies(self):
return []
class FortranLibrary:
"""Container for a bunch of Fortran routines.
"""
def __init__(self, src_dirs):
self._src_dirs = src_dirs
self.names_to_routines = {}
def _findRoutine(self, rname):
# 将输入的例程名转换为小写
rname = rname.lower()
# 遍历源目录列表中的每一个目录
for s in self._src_dirs:
# 构建可能的Fortran例程文件名
ffilename = os.path.join(s, rname + '.f')
# 如果文件存在,返回新创建的Fortran例程对象
if os.path.exists(ffilename):
return self._newFortranRoutine(rname, ffilename)
# 如果未找到文件,返回一个未知的Fortran例程对象
return UnknownFortranRoutine(rname)
def _newFortranRoutine(self, rname, filename):
# 创建并返回一个新的Fortran例程对象
return FortranRoutine(rname, filename)
def addIgnorableRoutine(self, rname):
"""Add a routine that we don't want to consider when looking at
dependencies.
"""
# 将例程名转换为小写
rname = rname.lower()
# 创建一个未知的Fortran例程对象
routine = UnknownFortranRoutine(rname)
# 将例程名和对象存储到类属性中
self.names_to_routines[rname] = routine
def addRoutine(self, rname):
"""Add a routine to the library.
"""
# 调用getRoutine方法以确保例程存在于库中
self.getRoutine(rname)
def getRoutine(self, rname):
"""Get a routine from the library. Will add if it's not found.
"""
# 创建一个唯一标识符列表
unique = []
# 将例程名转换为小写
rname = rname.lower()
# 从类属性中获取对应例程名的例程对象,若不存在则返回唯一标识符列表
routine = self.names_to_routines.get(rname, unique)
# 如果获取的是唯一标识符列表,则调用_findRoutine方法寻找并添加例程
if routine is unique:
routine = self._findRoutine(rname)
self.names_to_routines[rname] = routine
# 返回找到或者新添加的例程对象
return routine
def allRoutineNames(self):
"""Return the names of all the routines.
"""
# 返回类属性中所有例程名组成的列表
return list(self.names_to_routines.keys())
def allRoutines(self):
"""Return all the routines.
"""
# 返回类属性中所有例程对象组成的列表
return list(self.names_to_routines.values())
def resolveAllDependencies(self):
"""Try to add routines to the library to satisfy all the dependencies
for each routine in the library.
Returns a set of routine names that have the dependencies unresolved.
"""
# 已处理的例程名集合
done_this = set()
# 上次循环未解决的例程名集合
last_todo = set()
while True:
# 获取所有未处理的例程名集合
todo = set(self.allRoutineNames()) - done_this
# 如果当前未处理集合与上次相同,则退出循环
if todo == last_todo:
break
# 遍历每一个未处理的例程名
for rn in todo:
# 获取该例程名对应的例程对象
r = self.getRoutine(rn)
# 获取该例程对象的所有依赖例程名
deps = r.dependencies()
# 为每一个依赖例程名添加到库中
for d in deps:
self.addRoutine(d)
# 将该例程名标记为已处理
done_this.add(rn)
# 更新上次未处理的例程名集合
last_todo = todo
# 返回未解决依赖的例程名集合
return todo
# LapackLibrary 类,继承自 FortranLibrary 类
class LapackLibrary(FortranLibrary):
# 重写父类方法 _newFortranRoutine
def _newFortranRoutine(self, rname, filename):
# 调用父类方法创建新的 FortranRoutine 对象
routine = FortranLibrary._newFortranRoutine(self, rname, filename)
# 根据文件名和函数名设置 routine 的 type 属性
if 'blas' in filename.lower():
routine.type = 'blas'
elif 'install' in filename.lower():
routine.type = 'config'
elif rname.startswith('z'):
routine.type = 'z_lapack'
elif rname.startswith('c'):
routine.type = 'c_lapack'
elif rname.startswith('s'):
routine.type = 's_lapack'
elif rname.startswith('d'):
routine.type = 'd_lapack'
else:
routine.type = 'lapack'
return routine
# 打印描述和给定类型的所有 routines 名称
def printRoutineNames(desc, routines):
print(desc)
for r in routines:
print('\t%s' % r.name)
# 根据给定的 wrapped_routines、ignores 和 lapack_dir 创建 LapackLibrary 对象
def getLapackRoutines(wrapped_routines, ignores, lapack_dir):
# 确定 BLAS 和 LAPACK 源码目录
blas_src_dir = os.path.join(lapack_dir, 'BLAS', 'SRC')
if not os.path.exists(blas_src_dir):
blas_src_dir = os.path.join(lapack_dir, 'blas', 'src')
lapack_src_dir = os.path.join(lapack_dir, 'SRC')
if not os.path.exists(lapack_src_dir):
lapack_src_dir = os.path.join(lapack_dir, 'src')
install_src_dir = os.path.join(lapack_dir, 'INSTALL')
if not os.path.exists(install_src_dir):
install_src_dir = os.path.join(lapack_dir, 'install')
# 创建 LapackLibrary 对象
library = LapackLibrary([install_src_dir, blas_src_dir, lapack_src_dir])
# 将 ignores 中的 routine 添加到忽略列表中
for r in ignores:
library.addIgnorableRoutine(r)
# 将 wrapped_routines 中的 routine 添加到 library 中
for w in wrapped_routines:
library.addRoutine(w)
# 解析所有依赖关系
library.resolveAllDependencies()
return library
# 从 wrapped_routines_file 中获取 wrapped routines 和 ignores
def getWrappedRoutineNames(wrapped_routines_file):
routines = []
ignores = []
with open(wrapped_routines_file) as fo:
for line in fo:
line = line.strip()
if not line or line.startswith('#'):
continue
if line.startswith('IGNORE:'):
line = line[7:].strip()
ig = line.split()
ignores.extend(ig)
else:
routines.append(line)
return routines, ignores
# 类型集合,包含了可能的 routine 类型
types = {'blas', 'lapack', 'd_lapack', 's_lapack', 'z_lapack', 'c_lapack', 'config'}
# 将 library 中每种类型的 routines 名称和依赖关系写入输出目录中的文件
def dumpRoutineNames(library, output_dir):
for typename in {'unknown'} | types:
routines = library.allRoutinesByType(typename)
filename = os.path.join(output_dir, typename + '_routines.lst')
with open(filename, 'w') as fo:
for r in routines:
deps = r.dependencies()
fo.write('%s: %s\n' % (r.name, ' '.join(deps)))
# 将 routines 中的所有源文件内容合并并写入 output_file
def concatenateRoutines(routines, output_file):
with open(output_file, 'w') as output_fo:
for r in routines:
with open(r.filename) as fo:
source = fo.read()
output_fo.write(source)
class F2CError(Exception):
pass
# 将 Fortran 文件名中的反斜杠替换为正斜杠,以适应不同操作系统路径格式
def runF2C(fortran_filename, output_dir):
fortran_filename = fortran_filename.replace('\\', '/')
try:
# 使用 subprocess 调用 f2c 转换 Fortran 文件为 C 文件,并指定输出目录
subprocess.check_call(
["f2c"] + F2C_ARGS + ['-d', output_dir, fortran_filename]
)
except subprocess.CalledProcessError:
# 如果调用出错,则抛出自定义异常 F2CError
raise F2CError
# 清理指定 C 文件中的源码,通过 clapack_scrub 模块进行处理
def scrubF2CSource(c_file):
with open(c_file) as fo:
source = fo.read()
# 调用 clapack_scrub 模块的 scrubSource 函数清理源码,并输出详细信息
source = clapack_scrub.scrubSource(source, verbose=True)
with open(c_file, 'w') as fo:
# 将清理后的源码写回原文件,并添加标准头部 HEADER
fo.write(HEADER)
fo.write(source)
# 确保指定的可执行文件名在系统路径中可找到,否则抛出 SystemExit 异常
def ensure_executable(name):
try:
which(name)
except Exception:
raise SystemExit(name + ' not found')
# 创建 LAPACK 符号重命名头文件,以避免符号冲突,并加入 BLAS/LAPACK 和 f2c 的重命名
def create_name_header(output_dir):
routine_re = re.compile(r'^ (subroutine|.* function)\s+(\w+)\(.*$',
re.I)
extern_re = re.compile(r'^extern [a-z]+ ([a-z0-9_]+)\(.*$')
# BLAS/LAPACK 符号集合
symbols = set(['xerbla'])
for fn in os.listdir(output_dir):
fn = os.path.join(output_dir, fn)
if not fn.endswith('.f'):
continue
with open(fn) as f:
for line in f:
m = routine_re.match(line)
if m:
# 提取并添加符号到集合中
symbols.add(m.group(2).lower())
# f2c 符号集合
f2c_symbols = set()
with open('f2c.h') as f:
for line in f:
m = extern_re.match(line)
if m:
# 提取并添加 f2c 符号到集合中
f2c_symbols.add(m.group(1))
with open(os.path.join(output_dir, 'lapack_lite_names.h'), 'w') as f:
f.write(HEADER_BLURB)
f.write(
"/*\n"
" * This file renames all BLAS/LAPACK and f2c symbols to avoid\n"
" * dynamic symbol name conflicts, in cases where e.g.\n"
" * integer sizes do not match with 'standard' ABI.\n"
" */\n")
# 重命名 BLAS/LAPACK 符号并写入文件
for name in sorted(symbols):
f.write("#define %s_ BLAS_FUNC(%s)\n" % (name, name))
# 也重命名 f2c 导出的符号并写入文件
f.write("\n"
"/* Symbols exported by f2c.c */\n")
for name in sorted(f2c_symbols):
f.write("#define %s numpy_lapack_lite_%s\n" % (name, name))
# 主程序入口,执行 LAPACK 转换和符号重命名操作
def main():
if len(sys.argv) != 3:
# 如果命令行参数不为3个,打印帮助文档并返回
print(__doc__)
return
# 确保系统能找到 patch 和 f2c 可执行文件
ensure_executable('f2c')
ensure_executable('patch')
# 读取命令行参数
wrapped_routines_file = sys.argv[1]
lapack_src_dir = sys.argv[2]
output_dir = os.path.join(os.path.dirname(__file__), 'build')
# 删除旧的输出目录并创建新的输出目录
shutil.rmtree(output_dir, ignore_errors=True)
os.makedirs(output_dir)
# 获取需要转换的 LAPACK 函数列表和忽略列表
wrapped_routines, ignores = getWrappedRoutineNames(wrapped_routines_file)
# 获取 LAPACK 函数库
library = getLapackRoutines(wrapped_routines, ignores, lapack_src_dir)
# 将 LAPACK 函数信息导出到指定的输出目录
dumpRoutineNames(library, output_dir)
# 遍历类型列表中的每个类型名
for typename in types:
# 构建对应的 Fortran 文件路径
fortran_file = os.path.join(output_dir, 'f2c_%s.f' % typename)
# 根据 Fortran 文件路径生成对应的 C 文件路径
c_file = fortran_file[:-2] + '.c'
# 打印正在创建的 C 文件名
print('creating %s ...' % c_file)
# 获取特定类型的所有例程
routines = library.allRoutinesByType(typename)
# 将所有例程连接起来并写入 Fortran 文件
concatenateRoutines(routines, fortran_file)
# 应用补丁文件
patch_file = os.path.basename(fortran_file) + '.patch'
# 如果补丁文件存在,则使用 subprocess 调用 patch 命令进行打补丁操作
if os.path.exists(patch_file):
subprocess.check_call(['patch', '-u', fortran_file, patch_file])
print("Patched {}".format(fortran_file))
try:
# 尝试运行 f2c 工具转换 Fortran 文件为 C 文件
runF2C(fortran_file, output_dir)
except F2CError:
# 如果转换失败,则打印错误信息
print('f2c failed on %s' % fortran_file)
break
# 清理生成的 C 文件的源代码
scrubF2CSource(c_file)
# 检查并应用 C 文件的补丁
c_patch_file = os.path.basename(c_file) + '.patch'
if os.path.exists(c_patch_file):
subprocess.check_call(['patch', '-u', c_file, c_patch_file])
# 打印空行,用于分隔不同文件处理的输出信息
print()
# 创建名称头文件
create_name_header(output_dir)
# 遍历输出目录中的文件
for fname in os.listdir(output_dir):
# 复制所有以 '.c' 结尾的文件或特定的头文件 'lapack_lite_names.h'
if fname.endswith('.c') or fname == 'lapack_lite_names.h':
print('Copying ' + fname)
# 将文件复制到当前脚本所在目录
shutil.copy(
os.path.join(output_dir, fname),
os.path.abspath(os.path.dirname(__file__)),
)
# 如果当前脚本作为主程序运行
if __name__ == '__main__':
# 调用主函数 main()
main()
.\numpy\numpy\linalg\lapack_lite\python_xerbla.c
/*
定义宏以清除 Py_ssize_t 的定义
包含 Python.h 头文件
包含 numpy 库的通用头文件和 nmpy_cblas.h 头文件
*/
/*
从原始手册页:
--------------------------
XERBLA 是 LAPACK 程序的错误处理程序。
如果输入参数具有无效值,则由 LAPACK 程序调用它。
将打印一条消息并停止执行。
不打印消息和停止执行,而是引发一个带有消息的 ValueError 异常。
参数:
-----------
srname: 错误消息中使用的子程序名称,最多六个字符。
结尾的空格会被跳过。
info: 无效参数的编号。
*/
CBLAS_INT BLAS_FUNC(xerbla)(char *srname, CBLAS_INT *info)
{
static const char format[] = "On entry to %.*s" \
" parameter number %d had an illegal value";
char buf[sizeof(format) + 6 + 4]; /* 6 for name, 4 for param. num. */
int len = 0; /* 子程序名称的长度 */
PyGILState_STATE save;
while( len<6 && srname[len]!='\0' )
len++;
while( len && srname[len-1]==' ' )
len--;
// 保证全局解释器锁(GIL)被获取
save = PyGILState_Ensure();
// 使用给定的格式化字符串生成错误消息
PyOS_snprintf(buf, sizeof(buf), format, len, srname, (int)*info);
// 设置 ValueError 异常并传递错误消息
PyErr_SetString(PyExc_ValueError, buf);
// 释放全局解释器锁(GIL)
PyGILState_Release(save);
// 返回 0,表示出错处理函数的返回值
return 0;
}
.\numpy\numpy\linalg\lapack_litemodule.c
/*
* 此模块由Doug Heisterkamp贡献
* Jim Hugunin进行了修改
* Jeff Whitaker进行了更多修改
*/
/* 定义取消过时 API 的宏 */
#define NPY_NO_DEPRECATED_API NPY_API_VERSION
/* 清除以前的 ssize_t 定义,以使用更安全的定义 */
#define PY_SSIZE_T_CLEAN
#include <Python.h>
/* 包含 NumPy 的数组对象头文件 */
#include "numpy/arrayobject.h"
/* 包含 NumPy 的 CBLAS 头文件 */
#include "npy_cblas.h"
/* 定义一个宏,用于生成 BLAS 函数名 */
#define FNAME(name) BLAS_FUNC(name)
/* 定义 Fortran 中使用的整型 */
typedef CBLAS_INT fortran_int;
#ifdef HAVE_BLAS_ILP64
/* 根据不同的数据类型和平台选择对应的 Fortran 整型格式 */
#if NPY_BITSOF_SHORT == 64
#define FINT_PYFMT "h"
#elif NPY_BITSOF_INT == 64
#define FINT_PYFMT "i"
#elif NPY_BITSOF_LONG == 64
#define FINT_PYFMT "l"
#elif NPY_BITSOF_LONGLONG == 64
#define FINT_PYFMT "L"
#else
/* 如果没有找到兼容的 64 位整型大小,则抛出错误 */
#error No compatible 64-bit integer size. \
Please contact NumPy maintainers and give detailed information about your \
compiler and platform, or dont try to use ILP64 BLAS
#endif
#else
/* 默认使用标准的 32 位整型 */
#define FINT_PYFMT "i"
#endif
/* 定义复数类型结构体 */
typedef struct { float r, i; } f2c_complex;
typedef struct { double r, i; } f2c_doublecomplex;
/* typedef long int (*L_fp)(); */
/* 声明外部链接的 BLAS 和 LAPACK 函数 */
extern fortran_int FNAME(dgelsd)(fortran_int *m, fortran_int *n, fortran_int *nrhs,
double a[], fortran_int *lda, double b[], fortran_int *ldb,
double s[], double *rcond, fortran_int *rank,
double work[], fortran_int *lwork, fortran_int iwork[], fortran_int *info);
extern fortran_int FNAME(zgelsd)(fortran_int *m, fortran_int *n, fortran_int *nrhs,
f2c_doublecomplex a[], fortran_int *lda,
f2c_doublecomplex b[], fortran_int *ldb,
double s[], double *rcond, fortran_int *rank,
f2c_doublecomplex work[], fortran_int *lwork,
double rwork[], fortran_int iwork[], fortran_int *info);
extern fortran_int FNAME(dgeqrf)(fortran_int *m, fortran_int *n, double a[], fortran_int *lda,
double tau[], double work[],
fortran_int *lwork, fortran_int *info);
extern fortran_int FNAME(zgeqrf)(fortran_int *m, fortran_int *n, f2c_doublecomplex a[], fortran_int *lda,
f2c_doublecomplex tau[], f2c_doublecomplex work[],
fortran_int *lwork, fortran_int *info);
extern fortran_int FNAME(dorgqr)(fortran_int *m, fortran_int *n, fortran_int *k, double a[], fortran_int *lda,
double tau[], double work[],
fortran_int *lwork, fortran_int *info);
extern fortran_int FNAME(zungqr)(fortran_int *m, fortran_int *n, fortran_int *k, f2c_doublecomplex a[],
fortran_int *lda, f2c_doublecomplex tau[],
f2c_doublecomplex work[], fortran_int *lwork, fortran_int *info);
extern fortran_int FNAME(xerbla)(char *srname, fortran_int *info);
/* 定义 LapackError 的静态 PyObject 指针 */
static PyObject *LapackError;
/* 定义一个宏,用于简化错误处理 */
#define TRY(E) if (!(E)) return NULL
/* 定义一个静态函数,用于检查 Python 对象 */
static int
check_object(PyObject *ob, int t, char *obname,
char *tname, char *funname)
{
# 检查参数 ob 是否为 NumPy 数组,如果不是则抛出错误信息并返回 0
if (!PyArray_Check(ob)) {
PyErr_Format(LapackError,
"Expected an array for parameter %s in lapack_lite.%s",
obname, funname);
return 0;
}
# 检查参数 ob 是否为 C 连续存储的 NumPy 数组,如果不是则抛出错误信息并返回 0
else if (!PyArray_IS_C_CONTIGUOUS((PyArrayObject *)ob)) {
PyErr_Format(LapackError,
"Parameter %s is not contiguous in lapack_lite.%s",
obname, funname);
return 0;
}
# 检查参数 ob 是否为指定类型 t 的 NumPy 数组,如果不是则抛出错误信息并返回 0
else if (!(PyArray_TYPE((PyArrayObject *)ob) == t)) {
PyErr_Format(LapackError,
"Parameter %s is not of type %s in lapack_lite.%s",
obname, tname, funname);
return 0;
}
# 检查参数 ob 是否具有非本机字节顺序,如果是则抛出错误信息并返回 0
else if (PyArray_ISBYTESWAPPED((PyArrayObject *)ob)) {
PyErr_Format(LapackError,
"Parameter %s has non-native byte order in lapack_lite.%s",
obname, funname);
return 0;
}
# 如果所有条件都满足,则返回 1 表示通过参数检查
else {
return 1;
}
# 定义宏 CHDATA,将指针 p 强制转换为 char* 类型,并获取其指向的 NumPy 数组数据的指针
#define CHDATA(p) ((char *) PyArray_DATA((PyArrayObject *)p))
# 定义宏 SHDATA,将指针 p 强制转换为 short int* 类型,并获取其指向的 NumPy 数组数据的指针
#define SHDATA(p) ((short int *) PyArray_DATA((PyArrayObject *)p))
# 定义宏 DDATA,将指针 p 强制转换为 double* 类型,并获取其指向的 NumPy 数组数据的指针
#define DDATA(p) ((double *) PyArray_DATA((PyArrayObject *)p))
# 定义宏 FDATA,将指针 p 强制转换为 float* 类型,并获取其指向的 NumPy 数组数据的指针
#define FDATA(p) ((float *) PyArray_DATA((PyArrayObject *)p))
# 定义宏 CDATA,将指针 p 强制转换为 f2c_complex* 类型,并获取其指向的 NumPy 数组数据的指针
#define CDATA(p) ((f2c_complex *) PyArray_DATA((PyArrayObject *)p))
# 定义宏 ZDATA,将指针 p 强制转换为 f2c_doublecomplex* 类型,并获取其指向的 NumPy 数组数据的指针
#define ZDATA(p) ((f2c_doublecomplex *) PyArray_DATA((PyArrayObject *)p))
# 定义宏 IDATA,将指针 p 强制转换为 fortran_int* 类型,并获取其指向的 NumPy 数组数据的指针
#define IDATA(p) ((fortran_int *) PyArray_DATA((PyArrayObject *)p))
# 定义 lapack_lite_dgelsd 函数,接收 Python 的调用,执行 dgelsd LAPACK 求解操作
static PyObject *
lapack_lite_dgelsd(PyObject *NPY_UNUSED(self), PyObject *args)
{
fortran_int lapack_lite_status; // LAPACK 操作返回状态
fortran_int m; // 矩阵 A 的行数
fortran_int n; // 矩阵 A 的列数
fortran_int nrhs; // 矩阵 B 的列数
PyObject *a; // NumPy 数组对象,存储矩阵 A 的数据
fortran_int lda; // 矩阵 A 的列数
PyObject *b; // NumPy 数组对象,存储矩阵 B 的数据
fortran_int ldb; // 矩阵 B 的列数
PyObject *s; // NumPy 数组对象,存储奇异值分解结果 S 的数据
double rcond; // 控制奇异值的截断参数
fortran_int rank; // 估计的矩阵 A 的秩
PyObject *work; // NumPy 数组对象,提供给 LAPACK 的工作空间
PyObject *iwork; // NumPy 数组对象,提供给 LAPACK 的整数工作空间
fortran_int lwork; // 工作空间的长度
fortran_int info; // LAPACK 操作的信息
TRY(PyArg_ParseTuple(args,
(FINT_PYFMT FINT_PYFMT FINT_PYFMT "O" FINT_PYFMT "O"
FINT_PYFMT "O" "d" FINT_PYFMT "O" FINT_PYFMT "O"
FINT_PYFMT ":dgelsd"),
&m,&n,&nrhs,&a,&lda,&b,&ldb,&s,&rcond,
&rank,&work,&lwork,&iwork,&info));
TRY(check_object(a,NPY_DOUBLE,"a","NPY_DOUBLE","dgelsd")); // 检查参数 a 是否为 NPY_DOUBLE 类型的 NumPy 数组
TRY(check_object(b,NPY_DOUBLE,"b","NPY_DOUBLE","dgelsd")); // 检查参数 b 是否为 NPY_DOUBLE 类型的 NumPy 数组
TRY(check_object(s,NPY_DOUBLE,"s","NPY_DOUBLE","dgelsd")); // 检查参数 s 是否为 NPY_DOUBLE 类型的 NumPy 数组
TRY(check_object(work,NPY_DOUBLE,"work","NPY_DOUBLE","dgelsd")); // 检查参数 work 是否为 NPY_DOUBLE 类型的 NumPy 数组
#ifndef NPY_UMATH_USE_BLAS64_
TRY(check_object(iwork,NPY_INT,"iwork","NPY_INT","dgelsd")); // 检查参数 iwork 是否为 NPY_INT 类型的 NumPy 数组
#else
TRY(check_object(iwork,NPY_INT64,"iwork","NPY_INT64","dgelsd")); // 检查参数 iwork 是否为 NPY_INT64 类型的 NumPy 数组
#endif
// 调用 LAPACK 中的 dgelsd 函数,进行最小二乘法求解
lapack_lite_status =
FNAME(dgelsd)(&m,&n,&nrhs,DDATA(a),&lda,DDATA(b),&ldb,
DDATA(s),&rcond,&rank,DDATA(work),&lwork,
IDATA(iwork),&info);
if (PyErr_Occurred()) {
return NULL;
}
// 构建返回值,包括 dgelsd 操作的结果信息
return Py_BuildValue(("{s:" FINT_PYFMT ",s:" FINT_PYFMT ",s:" FINT_PYFMT
",s:" FINT_PYFMT ",s:" FINT_PYFMT ",s:" FINT_PYFMT
",s:d,s:" FINT_PYFMT ",s:" FINT_PYFMT
",s:" FINT_PYFMT "}"),
"dgelsd_",lapack_lite_status,"m",m,"n",n,"nrhs",nrhs,
"lda",lda,"ldb",ldb,"rcond",rcond,"rank",rank,
"lwork",lwork,"info",info);
}
{
fortran_int lapack_lite_status; // 定义 LAPACK 函数返回状态变量
fortran_int m, n, lwork; // 定义矩阵维度 m, n 和工作数组大小 lwork
PyObject *a, *tau, *work; // 定义 Python 对象指针,分别用于矩阵 A、TAU 和工作数组
fortran_int lda; // 定义矩阵 A 的 leading dimension
fortran_int info; // 定义 LAPACK 函数信息变量
TRY(PyArg_ParseTuple(args,
(FINT_PYFMT FINT_PYFMT "O" FINT_PYFMT "OO"
FINT_PYFMT FINT_PYFMT ":dgeqrf"),
&m, &n, &a, &lda, &tau, &work, &lwork, &info));
// 解析传入的 Python 元组参数,获取 m, n, a, lda, tau, work, lwork 和 info 的值
/* check objects and convert to right storage order */
TRY(check_object(a, NPY_DOUBLE, "a", "NPY_DOUBLE", "dgeqrf"));
TRY(check_object(tau, NPY_DOUBLE, "tau", "NPY_DOUBLE", "dgeqrf"));
TRY(check_object(work, NPY_DOUBLE, "work", "NPY_DOUBLE", "dgeqrf"));
// 检查对象类型并确保存储顺序正确,针对矩阵 a、tau 和 work
lapack_lite_status =
FNAME(dgeqrf)(&m, &n, DDATA(a), &lda, DDATA(tau),
DDATA(work), &lwork, &info);
// 调用 LAPACK 的 dgeqrf 函数进行 QR 分解计算
if (PyErr_Occurred()) {
return NULL;
}
// 检查是否有 Python 异常发生,如有则返回空指针
return Py_BuildValue(("{s:" FINT_PYFMT ",s:" FINT_PYFMT ",s:" FINT_PYFMT
",s:" FINT_PYFMT ",s:" FINT_PYFMT ",s:" FINT_PYFMT "}"),
"dgeqrf_",
lapack_lite_status, "m", m, "n", n, "lda", lda,
"lwork", lwork, "info", info);
// 构建并返回包含函数执行结果的 Python 元组对象
}
static PyObject *
lapack_lite_dorgqr(PyObject *NPY_UNUSED(self), PyObject *args)
{
fortran_int lapack_lite_status;
fortran_int m, n, k, lwork;
PyObject *a, *tau, *work;
fortran_int lda;
fortran_int info;
TRY(PyArg_ParseTuple(args,
(FINT_PYFMT FINT_PYFMT FINT_PYFMT "O"
FINT_PYFMT "OO" FINT_PYFMT FINT_PYFMT
":dorgqr"),
&m, &n, &k, &a, &lda, &tau, &work, &lwork, &info));
// 解析传入的 Python 元组参数,获取 m, n, k, a, lda, tau, work, lwork 和 info 的值
TRY(check_object(a, NPY_DOUBLE, "a", "NPY_DOUBLE", "dorgqr"));
TRY(check_object(tau, NPY_DOUBLE, "tau", "NPY_DOUBLE", "dorgqr"));
TRY(check_object(work, NPY_DOUBLE, "work", "NPY_DOUBLE", "dorgqr"));
// 检查对象类型并确保存储顺序正确,针对矩阵 a、tau 和 work
lapack_lite_status =
FNAME(dorgqr)(&m, &n, &k, DDATA(a), &lda, DDATA(tau), DDATA(work),
&lwork, &info);
// 调用 LAPACK 的 dorgqr 函数进行 QR 分解计算
if (PyErr_Occurred()) {
return NULL;
}
// 检查是否有 Python 异常发生,如有则返回空指针
return Py_BuildValue("{s:i,s:i}", "dorgqr_", lapack_lite_status,
"info", info);
// 构建并返回包含函数执行结果的 Python 字典对象
}
static PyObject *
lapack_lite_zgelsd(PyObject *NPY_UNUSED(self), PyObject *args)
{
fortran_int lapack_lite_status;
fortran_int m;
fortran_int n;
fortran_int nrhs;
PyObject *a;
fortran_int lda;
PyObject *b;
fortran_int ldb;
PyObject *s;
double rcond;
fortran_int rank;
PyObject *work;
fortran_int lwork;
PyObject *rwork;
PyObject *iwork;
fortran_int info;
# 尝试解析传入的参数元组,根据指定格式字符串匹配参数,对应关系如下:
# m, n, nrhs, a, lda, b, ldb, s, rcond, rank, work, lwork, rwork, iwork, info
TRY(PyArg_ParseTuple(args,
(FINT_PYFMT FINT_PYFMT FINT_PYFMT "O" FINT_PYFMT
"O" FINT_PYFMT "Od" FINT_PYFMT "O" FINT_PYFMT
"OO" FINT_PYFMT ":zgelsd"),
&m,&n,&nrhs,&a,&lda,&b,&ldb,&s,&rcond,
&rank,&work,&lwork,&rwork,&iwork,&info));
# 尝试检查参数对象 a,确保其为 NPY_CDOUBLE 类型,用于 zgelsd 函数
TRY(check_object(a,NPY_CDOUBLE,"a","NPY_CDOUBLE","zgelsd"));
# 尝试检查参数对象 b,确保其为 NPY_CDOUBLE 类型,用于 zgelsd 函数
TRY(check_object(b,NPY_CDOUBLE,"b","NPY_CDOUBLE","zgelsd"));
# 尝试检查参数对象 s,确保其为 NPY_DOUBLE 类型,用于 zgelsd 函数
TRY(check_object(s,NPY_DOUBLE,"s","NPY_DOUBLE","zgelsd"));
# 尝试检查参数对象 work,确保其为 NPY_CDOUBLE 类型,用于 zgelsd 函数
TRY(check_object(work,NPY_CDOUBLE,"work","NPY_CDOUBLE","zgelsd"));
# 尝试检查参数对象 rwork,确保其为 NPY_DOUBLE 类型,用于 zgelsd 函数
TRY(check_object(rwork,NPY_DOUBLE,"rwork","NPY_DOUBLE","zgelsd"));
#ifndef NPY_UMATH_USE_BLAS64_
// 如果未定义 NPY_UMATH_USE_BLAS64_,调用 check_object 函数检查 iwork 对象,期望其类型为 NPY_INT,用于函数 zgelsd
TRY(check_object(iwork,NPY_INT,"iwork","NPY_INT","zgelsd"));
#else
// 如果定义了 NPY_UMATH_USE_BLAS64_,调用 check_object 函数检查 iwork 对象,期望其类型为 NPY_INT64,用于函数 zgelsd
TRY(check_object(iwork,NPY_INT64,"iwork","NPY_INT64","zgelsd"));
#endif
// 调用 LAPACK 函数 zgelsd 执行最小二乘解,对矩阵进行奇异值分解
lapack_lite_status =
FNAME(zgelsd)(&m,&n,&nrhs,ZDATA(a),&lda,ZDATA(b),&ldb,DDATA(s),&rcond,
&rank,ZDATA(work),&lwork,DDATA(rwork),IDATA(iwork),&info);
// 检查是否发生了 Python 异常,若有则返回空指针
if (PyErr_Occurred()) {
return NULL;
}
// 返回 LAPACK 函数 zgelsd 的执行结果和相关参数的 Python 对象表示
return Py_BuildValue(("{s:" FINT_PYFMT ",s:" FINT_PYFMT ",s:" FINT_PYFMT
",s:" FINT_PYFMT ",s:" FINT_PYFMT ",s:" FINT_PYFMT
",s:" FINT_PYFMT ",s:" FINT_PYFMT ",s:" FINT_PYFMT
"}"),
"zgelsd_",
lapack_lite_status,"m",m,"n",n,"nrhs",nrhs,"lda",lda,
"ldb",ldb,"rank",rank,"lwork",lwork,"info",info);
}
static PyObject *
lapack_lite_zgeqrf(PyObject *NPY_UNUSED(self), PyObject *args)
{
fortran_int lapack_lite_status;
fortran_int m, n, lwork;
PyObject *a, *tau, *work;
fortran_int lda;
fortran_int info;
// 尝试解析 Python 元组参数 args,解析后的参数依次赋值给 m, n, a, lda, tau, work, lwork, info
TRY(PyArg_ParseTuple(args,
(FINT_PYFMT FINT_PYFMT "O" FINT_PYFMT "OO"
FINT_PYFMT "" FINT_PYFMT ":zgeqrf"),
&m,&n,&a,&lda,&tau,&work,&lwork,&info));
// 检查并转换对象 a, tau, work 的存储顺序为 NPY_CDOUBLE
TRY(check_object(a,NPY_CDOUBLE,"a","NPY_CDOUBLE","zgeqrf"));
TRY(check_object(tau,NPY_CDOUBLE,"tau","NPY_CDOUBLE","zgeqrf"));
TRY(check_object(work,NPY_CDOUBLE,"work","NPY_CDOUBLE","zgeqrf"));
// 调用 LAPACK 函数 zgeqrf 执行 QR 分解
lapack_lite_status =
FNAME(zgeqrf)(&m, &n, ZDATA(a), &lda, ZDATA(tau), ZDATA(work),
&lwork, &info);
// 检查是否发生了 Python 异常,若有则返回空指针
if (PyErr_Occurred()) {
return NULL;
}
// 返回 LAPACK 函数 zgeqrf 的执行结果和相关参数的 Python 对象表示
return Py_BuildValue(("{s:" FINT_PYFMT ",s:" FINT_PYFMT
",s:" FINT_PYFMT ",s:" FINT_PYFMT
",s:" FINT_PYFMT ",s:" FINT_PYFMT "}"),
"zgeqrf_",lapack_lite_status,"m",m,"n",n,"lda",lda,"lwork",lwork,"info",info);
}
static PyObject *
lapack_lite_zungqr(PyObject *NPY_UNUSED(self), PyObject *args)
{
// lapack_lite 模块中的 zungqr 函数实现
fortran_int lapack_lite_status; // Lapack 函数调用返回状态
fortran_int m, n, k, lwork; // 整型变量 m, n, k, lwork
PyObject *a, *tau, *work; // Python 对象 a, tau, work
fortran_int lda; // Lapack 函数调用中的 lda 参数
fortran_int info; // Lapack 函数调用返回的信息状态
// 解析 Python 函数参数,格式化为 Lapack 函数调用的输入
TRY(PyArg_ParseTuple(args,
(FINT_PYFMT FINT_PYFMT FINT_PYFMT "O"
FINT_PYFMT "OO" FINT_PYFMT "" FINT_PYFMT
":zungqr"),
&m, &n, &k, &a, &lda, &tau, &work, &lwork, &info));
// 检查 Python 对象 a, tau, work 的类型是否符合预期
TRY(check_object(a,NPY_CDOUBLE,"a","NPY_CDOUBLE","zungqr"));
TRY(check_object(tau,NPY_CDOUBLE,"tau","NPY_CDOUBLE","zungqr"));
TRY(check_object(work,NPY_CDOUBLE,"work","NPY_CDOUBLE","zungqr"));
// 调用 Lapack 中的 zungqr 函数进行 QR 分解
lapack_lite_status =
FNAME(zungqr)(&m, &n, &k, ZDATA(a), &lda, ZDATA(tau), ZDATA(work),
&lwork, &info);
// 检查是否有 Python 异常发生,若有则返回空指针
if (PyErr_Occurred()) {
return NULL;
}
// 构建 Python 对象返回结果,包括 zungqr 函数的状态和信息
return Py_BuildValue(("{s:" FINT_PYFMT ",s:" FINT_PYFMT "}"),
"zungqr_",lapack_lite_status,
"info",info);
}
static PyObject *
lapack_lite_xerbla(PyObject *NPY_UNUSED(self), PyObject *args)
{
// 初始化 Lapack 错误信息的状态为 -1
fortran_int info = -1;
NPY_BEGIN_THREADS_DEF; // 定义多线程使用的变量
NPY_BEGIN_THREADS; // 开始多线程执行
// 调用 Lapack 错误处理函数 xerbla
FNAME(xerbla)("test", &info);
NPY_END_THREADS; // 结束多线程执行
// 检查是否有 Python 异常发生,若有则返回空指针
if (PyErr_Occurred()) {
return NULL;
}
// 返回 None
Py_RETURN_NONE;
}
#define STR(x) #x
#define lameth(name) {STR(name), lapack_lite_##name, METH_VARARGS, NULL}
static struct PyMethodDef lapack_lite_module_methods[] = {
lameth(dgelsd), // lapack_lite 模块中的 dgelsd 函数
lameth(dgeqrf), // lapack_lite 模块中的 dgeqrf 函数
lameth(dorgqr), // lapack_lite 模块中的 dorgqr 函数
lameth(zgelsd), // lapack_lite 模块中的 zgelsd 函数
lameth(zgeqrf), // lapack_lite 模块中的 zgeqrf 函数
lameth(zungqr), // lapack_lite 模块中的 zungqr 函数
lameth(xerbla), // lapack_lite 模块中的 xerbla 函数
{ NULL,NULL,0, NULL} // 方法定义结束的标志
};
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT, // 初始化 Python 模块定义头部
"lapack_lite", // 模块名为 lapack_lite
NULL, // 模块文档字符串为空
-1, // 模块状态为 -1,表示模块全局变量和线程的隔离
lapack_lite_module_methods, // 模块中包含的方法列表
NULL, // 模块的全局变量为 NULL
NULL, // 模块的 slot 常规方法为 NULL
NULL, // 模块的特殊内存分配器为 NULL
NULL // 模块的清理函数为 NULL
};
/* 模块初始化函数 */
PyMODINIT_FUNC PyInit_lapack_lite(void)
{
PyObject *m,*d; // Python 对象 m 和 d
m = PyModule_Create(&moduledef); // 创建名为 lapack_lite 的 Python 模块对象
if (m == NULL) {
return NULL;
}
import_array(); // 导入 NumPy 的数组对象
d = PyModule_GetDict(m); // 获取模块 m 的字典对象
LapackError = PyErr_NewException("lapack_lite.LapackError", NULL, NULL);
PyDict_SetItemString(d, "LapackError", LapackError); // 将 LapackError 异常对象加入模块字典
#ifdef HAVE_BLAS_ILP64
PyDict_SetItemString(d, "_ilp64", Py_True); // 设置模块字典中的 _ilp64 为 Py_True
#else
PyDict_SetItemString(d, "_ilp64", Py_False); // 设置模块字典中的 _ilp64 为 Py_False
#endif
return m; // 返回创建的 Python 模块对象
}
.\numpy\numpy\linalg\linalg.py
# 定义一个特殊的方法 __getattr__,用于在获取不存在的属性时执行
def __getattr__(attr_name):
# 导入警告模块,用于输出警告信息
import warnings
# 从 numpy.linalg 模块中导入 _linalg 对象
from numpy.linalg import _linalg
# 尝试获取 _linalg 对象的属性 attr_name
ret = getattr(_linalg, attr_name, None)
# 如果未找到该属性,则引发 AttributeError 异常
if ret is None:
raise AttributeError(
f"module 'numpy.linalg.linalg' has no attribute {attr_name}")
# 发出警告,说明 numpy.linalg.linalg 已被标记为私有,推荐使用 numpy.linalg._linalg 替代
warnings.warn(
"The numpy.linalg.linalg has been made private and renamed to "
"numpy.linalg._linalg. All public functions exported by it are "
f"available from numpy.linalg. Please use numpy.linalg.{attr_name} "
"instead.",
DeprecationWarning,
stacklevel=3
)
# 返回获取到的属性对象
return ret
.\numpy\numpy\linalg\tests\test_deprecations.py
"""Test deprecation and future warnings.
"""
# 导入 numpy 库,简写为 np
import numpy as np
# 从 numpy.testing 模块中导入 assert_warns 函数
from numpy.testing import assert_warns
# 定义测试函数 test_qr_mode_full_future_warning
def test_qr_mode_full_future_warning():
"""Check mode='full' FutureWarning.
In numpy 1.8 the mode options 'full' and 'economic' in linalg.qr were
deprecated. The release date will probably be sometime in the summer
of 2013.
"""
# 创建一个 2x2 的单位矩阵 a
a = np.eye(2)
# 断言调用 np.linalg.qr 函数时会产生 DeprecationWarning,使用 mode='full'
assert_warns(DeprecationWarning, np.linalg.qr, a, mode='full')
# 断言调用 np.linalg.qr 函数时会产生 DeprecationWarning,使用 mode='f'
assert_warns(DeprecationWarning, np.linalg.qr, a, mode='f')
# 断言调用 np.linalg.qr 函数时会产生 DeprecationWarning,使用 mode='economic'
assert_warns(DeprecationWarning, np.linalg.qr, a, mode='economic')
# 断言调用 np.linalg.qr 函数时会产生 DeprecationWarning,使用 mode='e'
assert_warns(DeprecationWarning, np.linalg.qr, a, mode='e')