我目前正在使用Python中的Fortran分位数回归代码来提高计算效率。 Fortran函数的输入X矩阵需要秩2-d数组。
然而,当我试图从Python运行单变量分位数回归时,Python内核崩溃了。
但是当X有2个或更多维度参数时,一切运行良好。这是Fortran代码的变量定义部分。
C Output from Public domain Ratfor, version 1.0
subroutine rqbr(m,nn,m5,n3,n4,a,b,t,toler,ift,x,e,s,wa,wb,nsol,nds
*ol,sol,dsol,lsol,h,qn,cutoff,ci,tnmat,big,lci1)
integer i,j,k,kl,kount,kr,l,lsol,m,m1,m2,m3,m4,m5,ift
integer n,n1,n2,n3,nsol,ndsol,out,s(m),h(nn,nsol)
integer nn,n4,idxcf
logical stage,test,init,iend,lup
logical lci1,lci2,skip
double precision a1,aux,b1,big,d,dif,pivot,smax,t,t0,t1,tnt
double precision min,max,toler,zero,half,one,two
double precision b(m),sol(n3,nsol),a(m,nn),x(nn),wa(m5,n4),wb(m)
double precision sum,e(m),dsol(m,ndsol)
double precision qn(nn),cutoff,ci(4,nn),tnmat(4,nn),tnew,told,tn
parameter( zero = 0.d0)
parameter( one = 1.d0)
parameter( two = 2.d0)
Cf2py intent(in) :: m,nn,m5,n3,n4,a,b,t,toler,nsol,ndsol,cutoff,big,lci1
Cf2py intent(out) :: x,e,sol,dsol,h,ci,tnmat
Cf2py intent(in,out) :: ift,s,wa,wb,lsol,qn
Cf2py depend(m,nn) a
Cf2py depend(m) b
Cf2py depend(nn) x
Cf2py depend(m) e
Cf2py depend(m) s
Cf2py depend(m5,n4) wa
Cf2py depend(m) wb
Cf2py depend(n3,nsol) sol
Cf2py depend(m,ndsol) dsol
Cf2py depend(nn,nsol) h
Cf2py depend(nn) qn
Cf2py depend(nn) ci
Cf2py depend(nn) tnmat
n=nn
ift = 0
wa(m+2,nn+1) = one
if(m5.ne.m+5)then
ift = 3
endif
if(n3.ne.n+3)then
ift = 4
endif
if(n4.ne.n+4)then
ift = 5
endif
if(m.le.zero.or.n.le.zero)then
ift = 6
endif
if(ift.le.two)then
half = one/two
iend = .true.
lci2 = .false.
lup = .true.
skip = .false.
idxcf = 0
tnew = zero
tn = zero
m1 = m+1
n1 = n+1
n2 = n+2
m2 = m+2
m3 = m+3
m4 = m+4
do23010 j = 1,n
x(j) = zero
23010 continue
23011 continue
do23012 i = 1,m
e(i) = zero
23012 continue
23013 continue
if(t.lt.zero.or.t.gt.one)then
t0 = one/(two*float(m))
t1 = one-t0
t = t0
iend = .false.
lci1 = .false.
endif
23016 continue
do23019 i = 1,m
k = 1
do23021 j = 1,nn
if(k.le.nn)then
if(j.eq.idxcf)then
skip = .true.
else
skip = .false.
endif
if(.not.skip)then
wa(i,k) = a(i,j)
k = k+1
endif
endif
23021 continue
23022 continue
wa(i,n4) = n+i
wa(i,n2) = b(i)
if(idxcf .ne. 0)then
wa(i,n3) = tnew*a(i,idxcf)
else
wa(i,n3) = zero
endif
wa(i,n1) = wa(i,n2)-wa(i,n3)
if(wa(i,n1).lt.zero)then
do23033 j = 1,n4
wa(i,j) = -wa(i,j)
23033 continue
23034 continue
endif
23019 continue
23020 continue
do23035 j = 1,n
wa(m4,j) = j
wa(m2,j) = zero
wa(m3,j) = zero
do23037 i = 1,m
aux = sign(one,wa(m4,j))*wa(i,j)
wa(m2,j) = wa(m2,j)+aux*(one-sign(one,wa(i,n4)))
wa(m3,j) = wa(m3,j)+aux*sign(one,wa(i,n4))
23037 continue
23038 continue
wa(m3,j) = two*wa(m3,j)
23035 continue
23036 continue
dif = zero
init = .false.
if(.not.lci2)then
do23041 k = 1,n
wa(m5,k) = zero
do23043 i = 1,m
wa(m5,k) = wa(m5,k)+a(i,k)
23043 continue
23044 continue
wa(m5,k) = wa(m5,k)/float(m)
23041 continue
23042 continue
endif
lsol = 1
kount = 0
23045 continue
do23048 j = 1,n
wa(m1,j) = wa(m2,j)+wa(m3,j)*t
23048 continue
23049 continue
if(.not.init)then
stage = .true.
kr = 1
kl = 1
go to 30
endif
23052 continue
stage = .false.
23055 continue
max = -big
do23058 j = kr,n
d = wa(m1,j)
if(d.lt.zero)then
if(d.gt.(-two))then
goto 23058
endif
d = -d-two
endif
if(d.gt.max)then
max = d
in = j
endif
23058 continue
23059 continue
if(max.le.toler)then
goto 23054
endif
if(wa(m1,in).le.zero)then
do23070 i = 1,m4
wa(i,in) = -wa(i,in)
23070 continue
23071 continue
wa(m1,in) = wa(m1,in)-two
wa(m2,in) = wa(m2,in)-two
endif
23072 continue
k = 0
do23075 i = kl,m
d = wa(i,in)
if(d.gt.toler)then
k = k+1
wb(k) = wa(i,n1)/d
s(k) = i
test = .true.
endif
23075 continue
23076 continue
23079 continue
if(k.le.0)then
test = .false.
else
min = big
do23084 i = 1,k
if(wb(i).lt.min)then
j = i
min = wb(i)
out = s(i)
endif
23084 continue
23085 continue
wb(j) = wb(k)
s(j) = s(k)
k = k-1
endif
if(.not.test.and.stage)then
goto 23081
endif
if(.not.test)then
goto 23047
endif
pivot = wa(out,in)
if(wa(m1,in)-pivot-pivot.le.toler)then
go to 10
endif
do23094 j = kr,n3
d = wa(out,j)
wa(m1,j) = wa(m1,j)-d-d
wa(m2,j) = wa(m2,j)-d-d
wa(out,j) = -d
23094 continue
23095 continue
wa(out,n4) = -wa(out,n4)
23080 goto 23079
23081 continue
do23096 i = 1,m4
d = wa(i,kr)
wa(i,kr) = wa(i,in)
wa(i,in) = d
23096 continue
23097 continue
kr = kr+1
go to 20
10 do23098 j = kr,n3
if(j.ne.in)then
wa(out,j) = wa(out,j)/pivot
endif
23098 continue
23099 continue
do23102 i = 1,m3
if(i.ne.out)then
d = wa(i,in)
do23106 j = kr,n3
if(j.ne.in)then
wa(i,j) = wa(i,j)-d*wa(out,j)
endif
23106 continue
23107 continue
endif
23102 continue
23103 continue
do23110 i = 1,m3
if(i.ne.out)then
wa(i,in) = -wa(i,in)/pivot
endif
23110 continue
23111 continue
wa(out,in) = one/pivot
d = wa(out,n4)
wa(out,n4) = wa(m4,in)
wa(m4,in) = d
kount = kount+1
if(.not.stage)then
goto 23074
endif
kl = kl+1
do23116 j = kr,n4
d = wa(out,j)
wa(out,j) = wa(kount,j)
wa(kount,j) = d
23116 continue
23117 continue
20 if(kount+kr.eq.n1)then
goto 23057
endif
30 max = -one
do23120 j = kr,n
if(abs(wa(m4,j)).le.n)then
d = abs(wa(m1,j))
if(d.gt.max)then
max = d
in = j
endif
endif
23120 continue
23121 continue
if(wa(m1,in).lt.zero)then
do23128 i = 1,m4
wa(i,in) = -wa(i,in)
23128 continue
23129 continue
endif
23073 goto 23072
23074 continue
23056 goto 23055
23057 continue
23053 goto 23052
23054 continue
if(kr.eq.1)then
do23132 j = 1,n
d = abs(wa(m1,j))
if(d.le.toler.or.two-d.le.toler)then
ift = 1
wa(m2,nn+1) = zero
go to 80
endif
23132 continue
23133 continue
endif
80 kount = 0
sum = zero
if(.not.lci2)then
do23138 i = 1,kl-1
k = wa(i,n4)*sign(one,wa(i,n4))
x(k) = wa(i,n1)*sign(one,wa(i,n4))
23138 continue
23139 continue
endif
do23140 i = 1,n
kd = abs(wa(m4,i))-n
dsol(kd,lsol) = one+wa(m1,i)/two
if(wa(m4,i).lt.zero)then
dsol(kd,lsol) = one-dsol(kd,lsol)
endif
if(.not.lci2)then
sum = sum + x(i)*wa(m5,i)
sol(i+3,lsol) = x(i)
h(i,lsol) = kd
endif
23140 continue
23141 continue
do23146 i = kl,m
kd = abs(wa(i,n4))-n
if(wa(i,n4).lt.zero)then
dsol(kd,lsol) = zero
endif
if(wa(i,n4).gt.zero)then
dsol(kd,lsol) = one
endif
23146 continue
23147 continue
if(.not.lci2)then
sol(1,lsol) = smax
sol(2,lsol) = sum
sum = zero
do23154 j=kl,m
d = wa(j,n1)*sign(one,wa(j,n4))
sum = sum + d*(smax + half*(sign(one,d) - one))
23154 continue
23155 continue
sol(3,lsol) = sum
do23156 i=1,m
dsol(i,lsol+1) = dsol(i,lsol)
23156 continue
23157 continue
endif
if(lci2)then
a1 = zero
do23160 i = 1,m
a1 = a1+a(i,idxcf)*(dsol(i,lsol)+t-one)
23160 continue
23161 continue
tn = a1/sqrt(qn(idxcf)*t*(one-t))
if(abs(tn).lt.cutoff)then
if(lup)then
smax = big
else
smax = -big
endif
do23166 i =1,kl-1
k = wa(i,n4)*sign(one,wa(i,n4))
sol(k,1) = wa(i,n2)*sign(one,wa(i,n4))
sol(k,2) = wa(i,n3)*sign(one,wa(i,n4))/tnew
23166 continue
23167 continue
do23168 i = kl,m
a1 = zero
b1 = zero
k = wa(i,n4)*sign(one,wa(i,n4))-n
l = 1
do23170 j = 1,n
if(j.eq.idxcf)then
l = l+1
endif
a1 = a1 + a(k,l)*sol(j,1)
b1 = b1 + a(k,l)*sol(j,2)
l = l+1
23170 continue
23171 continue
tnt = (b(k)-a1)/(a(k,idxcf)-b1)
if(lup)then
if(tnt.gt.tnew)then
if(tnt.lt.smax)then
smax = tnt
out = i
endif
endif
else
if(tnt.lt.tnew)then
if(tnt.gt.smax)then
smax = tnt
out = i
endif
endif
endif
23168 continue
23169 continue
if(lup)then
told = tnew
tnew = smax + toler
ci(3,idxcf) = told - toler
tnmat(3,idxcf) = tn
if(.not.(tnew .lt. big-toler))then
ci(3,idxcf) = big
ci(4,idxcf) = big
tnmat(3,idxcf) = tn
tnmat(4,idxcf) = tn
lup = .false.
go to 70
endif
else
told = tnew
tnew = smax - toler
ci(2,idxcf) = told + toler
tnmat(2,idxcf) = tn
if(.not.(tnew .gt. -big+toler))then
ci(2,idxcf) = -big
ci(1,idxcf) = -big
tnmat(2,idxcf) = tn
tnmat(1,idxcf) = tn
lup = .true.
go to 60
endif
endif
do23190 i = 1,m
wa(i,n3) = wa(i,n3)/told*tnew
wa(i,n1) = wa(i,n2) - wa(i,n3)
23190 continue
23191 continue
do23192 j = kr,n3
d = wa(out,j)
wa(m1,j) = wa(m1,j) -d -d
wa(m2,j) = wa(m2,j) -d -d
wa(out,j) = -d
23192 continue
23193 continue
wa(out,n4) = -wa(out,n4)
init = .true.
else
if(lup)then
ci(4,idxcf) = tnew - toler
tnmat(4,idxcf) = tn
lup = .false.
go to 70
else
ci(1,idxcf) = tnew + toler
tnmat(1,idxcf) = tn
lup = .true.
go to 60
endif
endif
endif
if((iend).and.(.not.lci2))then
go to 40
endif
if(.not.lci2)then
init = .true.
lsol = lsol+1
do23200 i = 1,m
s(i) = zero
23200 continue
23201 continue
do23202 j = 1,n
x(j) = zero
23202 continue
23203 continue
smax = two
do23204 j = 1,n
b1 = wa(m3,j)
a1 = (-two-wa(m2,j))/b1
b1 = -wa(m2,j)/b1
if(a1.ge.t)then
if(a1.lt.smax)then
smax = a1
dif = (b1-a1)/two
endif
endif
if(b1.gt.t)then
if(b1.lt.smax)then
smax = b1
dif = (b1-a1)/two
endif
endif
23204 continue
23205 continue
tnt = smax+toler*(one+abs(dif))
if(tnt.ge.t1+toler)then
iend = .true.
endif
t = tnt
if(iend)then
t = t1
endif
endif
23046 goto 23045
23047 continue
wa(m2,nn+1) = two
ift = 2
go to 50
40 if(lsol.gt.2)then
sol(1,1) = zero
sol(3,1) = zero
sol(1,lsol) = one
sol(3,lsol) = zero
do23220 i = 1,m
dsol(i,1) = one
dsol(i,lsol) = zero
dsol(i,lsol+1) = zero
23220 continue
23221 continue
endif
l = kl-1
do23222 i = 1,l
if(wa(i,n1).lt.zero)then
do23226 j = kr,n4
wa(i,j) = -wa(i,j)
23226 continue
23227 continue
endif
23222 continue
23223 continue
50 sum = zero
if(.not.lci2)then
do23230 i = kl,m
k = wa(i,n4)*sign(one,wa(i,n4))
d = wa(i,n1)*sign(one,wa(i,n4))
sum = sum+d*sign(one,d)*(half+sign(one,d)*(t-half))
k = k-n
e(k) = d
23230 continue
23231 continue
wa(m2,n2) = kount
wa(m1,n2) = n1-kr
wa(m1,n1) = sum
endif
if(wa(m2,nn+1).eq.two)then
goto 23018
endif
if(.not.lci1)then
goto 23018
endif
if(.not.lci2)then
lci2 = .true.
n = nn-1
n1 = n+1
n2 = n+2
n3 = n+3
n4 = n+4
60 idxcf = idxcf+1
if(idxcf.gt.nn)then
goto 23018
endif
70 if(lup)then
tnew = x(idxcf)+toler
told = tnew
ci(3,idxcf) = x(idxcf)
tnmat(3,idxcf) = zero
else
tnew = x(idxcf)-toler
told = tnew
ci(2,idxcf) = x(idxcf)
tnmat(2,idxcf) = zero
endif
endif
23017 goto 23016
23018 continue
do23242 i=1,m
dsol(i,lsol) = dsol(i,lsol+1)
23242 continue
23243 continue
endif
return
end
在代码中' a'需要是(m,nn),这是一个二维秩。我假设nn可能是1?
我从Python运行的是:
import rqbr2
import numpy as np
def uniqr(X,y,tau):
m=X.shape[0]
nn=X.ndim
m5=m+5
n3=nn+3
n4=nn+4
t=tau
toler=0.001
ift=0
s=np.zeros((1,m))
wa=np.zeros((m5,n4))
wb=np.zeros((1,m))
nsol=2
ndsol=2
lsol=0
qn=np.zeros((1,nn))
cutoff=1.96
big=10000.0
lci1=True
z=rqbr2.rqbr(m,nn,m5,n3,n4,X,y,t,toler,ift,s,
wa,wb,nsol,ndsol,lsol,qn,cutoff,big,lci1)
yhat=np.dot(X,z[1])
beta=z[1]
return beta,yhat
X=np.array([1,3,5,7])
y=np.array([8,5,4,3])
tau=0.7
如果我尝试玩具示例说
X=np.array([1,3,5,7])
y=np.array([8,5,4,3])
tau=0.7
内核会立即崩溃。以下是可能显示的错误消息之一。
Segmentation fault (core dumped)
Backtrace消息:
#0 rqbr (m=<optimized out>, nn=1, m5=9, n3=3, n4=4, a=..., b=...,
t=0.69999999999999996, toler=0.001, ift=0, x=..., e=..., s=..., wa=...,
wb=..., nsol=2, ndsol=2, sol=..., dsol=..., lsol=1, h=..., qn=...,
cutoff=1.96, ci=..., tnmat=..., big=10000, lci1=.TRUE.) at rqbr2.f:229
#1 0x00007ffff69e0c02 in f2py_rout_rqbr2_rqbr (capi_self=<optimized out>,
capi_args=<optimized out>, capi_keywds=<optimized out>,
f2py_func=0x7ffff69e3200 <rqbr>)
at /tmp/tmpyQgumN/src.linux-x86_64-2.7/rqbr2module.c:553
#2 0x00000000004c15bf in PyEval_EvalFrameEx ()
#3 0x00000000004c136f in PyEval_EvalFrameEx ()
#4 0x00000000004b9ab6 in PyEval_EvalCodeEx ()
#5 0x00000000004eb30f in ?? ()
#6 0x00000000004e5422 in PyRun_FileExFlags ()
#7 0x00000000004e3cd6 in PyRun_SimpleFileExFlags ()
#8 0x0000000000493ae2 in Py_Main ()
#9 0x00007ffff7810830 in __libc_start_main (main=0x4934c0 <main>, argc=2,
argv=0x7fffffffe578, init=<optimized out>, fini=<optimized out>,
rtld_fini=<optimized out>, stack_end=0x7fffffffe568)
at ../csu/libc-start.c:291
#10 0x00000000004933e9 in _start ()
但是如果
X=np.array([[1,2],[3,5],[5,6],[7,8]])
我会得到我想要的结果:
(array([-9.66666667, 8.83333333]), array([ 8. , 15.16666667, 4.66666667, 3. ]))
任何建议都会有所帮助,谢谢。