Skip to content

Commit 796ab11

Browse files
committed
lapack
1 parent f44dcce commit 796ab11

7 files changed

Lines changed: 84 additions & 30 deletions

File tree

k+/blas.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,4 @@ void blas(void){
3535
reg(rot, "rot",4);
3636
reg(gemv,"gemv",7);
3737
}
38-
__attribute((section("reg")))void*rblas=blas;
38+
__attribute((section("rek")))void*rblas=blas;

k+/curl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@ uint64_t kurl(uint64_t x){
2020
dx(x);return r;}
2121

2222
void curl(void){reg(kurl,"curl",1);}
23-
__attribute((section("reg")))void*rcurl=curl;
23+
__attribute((section("rek")))void*rcurl=curl;

k+/lapack.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,48 @@
1+
int LAPACKE_dgesv(int,int,int,double*,int,int*,double*,int);
2+
int LAPACKE_zgesv(int,int,int,double*,int,int*,double*,int);
3+
int LAPACKE_dgels(int,char,int,int,int,double*,int,double*,int);
4+
int LAPACKE_zgels(int,char,int,int,int,double*,int,double*,int);
5+
int LAPACKE_dsyev(int,char,char,int,double*,int,double*);
6+
int LAPACKE_zheev(int,char,char,int,double*,int,double*);
7+
int LAPACKE_dgeev(int,char,char,int,double*,int,double*,double*,double*,int,double*,int);
8+
int LAPACKE_zgeev(int,char,char,int,double*,int,double*, double*,int,double*,int);
9+
int LAPACKE_dgesvd(int,char,char,int,int,double*,int,double*,double*,int,double*,int,double*);
10+
int LAPACKE_zgesvd(int,char,char,int,int,double*,int,double*,double*,int,double*,int,double*);
11+
12+
uint64_t gesv(uint64_t x){ //[A;B]
13+
uint64_t A=FZ(rx(x0(x))),B=FZ(ati(x,1));
14+
int32_t n=(int32_t)sqrt(nn(A));if(n*n!=nn(A))trap();
15+
int32_t nb=nn(B),k=nb/n;if(nb!=k*n)trap();
16+
int32_t t=maxtype(A,B);A=use(uptype(A,t));B=use(uptype(B,t));
17+
int*p=malloc(4*n);int r;
18+
if(t==zt)r=LAPACKE_zgesv(102,n,k,FK(A),n,p,FK(B),n);
19+
else r=LAPACKE_dgesv(102,n,k,FK(A),n,p,FK(B),n);
20+
free(p);
21+
if(r)trap();
22+
dx(A);
23+
return B;
24+
}
25+
uint64_t gels(uint64_t x){ //[rows;A;B]
26+
uint64_t M=x0(x),A=FZ(rx(x1(x))),B=FZ(ati(x,2));
27+
int32_t m=(int32_t)M;if(tp(M)!=it)trap();
28+
int32_t n=nn(A)/m;if(n*m!=nn(A)||m<n)trap();
29+
int32_t nb=nn(B),k=nb/m;if(n*k!=nb)trap();
30+
int32_t r,t=maxtype(A,B);A=use(uptype(A,t));B=use(uptype(B,t));
31+
if(t==zt)r=LAPACKE_zgels(102,'N',m,n,k,FK(A),m,FK(B),m);
32+
else r=LAPACKE_dgels(102,'N',m,n,k,FK(A),m,FK(B),m);
33+
dx(A);return B;
34+
}
35+
void lapack(void){
36+
reg(gesv,"gesv",2);
37+
reg(gels,"gels",3);
38+
//reg(geev,"geev",1);
39+
//reg(geev,"geeV",1);
40+
//reg(geev,"gesvd",1);
41+
//reg(geev,"gesvD",1);
42+
}
43+
__attribute((section("rek")))void*rlapack=lapack;
44+
45+
146
/*
247
#include<stdlib.h>
348
#include<string.h>

k+/readme

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# k+ extends k.c with some c-libraries using the native function type.
2-
# blas lapack fftw lp_solve ode specfun rmath curl sqlite..
2+
# blas lapack fftw lp_solve ode specfun curl sqlite..
33
#
44
# m.awk also replaces the builtin math functions with libm.
55
#
@@ -19,14 +19,22 @@
1919
# dot dotc todo
2020
# gemv[a;A;rA;op;b;y;x] c:fz A:FZ b:fz y:FZ a*A*x+b*y
2121
#
22+
# LAPACK
23+
# gesv[A;b] or b,b,.. solve Ax=b, both col-major flat vectors
24+
# gels[n;A;b] or b,b,.. solve Ax=b least squares
25+
#
26+
# SPARSE suitesparse:umfpack spqr
27+
# spsolve[A;b] or (b;b;..) solve sparse system
28+
# spqr[A;b] or b,b,.. solve sparse least squares
29+
#
2230
# CURL
2331
# curl"https://ktye.github.io/k.png"
2432
#
25-
# RMATH (r-mathlib)
33+
# RMATH (r-mathlib standalone)
2634

2735
# dependencies linux/windows, see deps
28-
# - linux(debian) see deps
29-
# - windows(mingw64) see deps.$pacman -S mingw-w64-x86_64-lpsolve
36+
# - linux(debian13) see deps
37+
# - windows(mingw64) see deps
3038

3139
set -e
3240
set -x
@@ -43,10 +51,11 @@ cat l.c>>k.c
4351

4452

4553
#these lines can be uncommented individually to exclude a package:
46-
#cat blas.c>>k.c;L="$L -lopenblas"
47-
#cat curl.c>>k.c;L="$L -lcurl"
54+
cat blas.c>>k.c;L="$L -lopenblas"
55+
cat lapack.c>>k.c;L="$L -llapacke"
56+
cat curl.c>>k.c;L="$L -lcurl"
4857
cat sparse.c>>k.c;L="$L -lumfpack -lspqr -lcholmod"
49-
#cat rmath.c>>k.c;L="$L Rmath.dll" #-lRmath
58+
#cat rmath.c>>k.c;L="$L -lRmath"
5059
# k.c
5160

5261
#type help to see a the list of all registered functions and their arity

k+/rmath.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ rnorm(n, mean = 0, sd = 1)
66
*/
77

88
//c/dat/r/R-4.5.1/src/include/Rmath.h
9-
double dnorm5(double,double,double,int);
9+
double dnorm4(double,double,double,int);
1010
double pnorm(double,double,double,int,int);
1111
double qnorm(double,double,double,int,int);
1212
double rnorm(double,double);
@@ -20,16 +20,15 @@ double rnorm(double,double);
2020
//t(2double) (student t dist)
2121
//cauchy
2222
//exp
23+
//..
2324

24-
25-
26-
uint64_t dnrm(uint64_t x){x=fF(x);
27-
if(tp(x)<16){dx(x);return Kf(F64((int32_t)x));};
25+
uint64_t dnrm(uint64_t x){x=fF(Fst(x));
26+
if(tp(x)<16){dx(x);return Kf(dnorm4(F64((int32_t)x),0,1,0));};
2827
x=use(x);int32_t e=ep(x);
29-
for(int32_t p=(int32_t)x;p<e;p+=8)SetF64(p,dnorm5(F64(p),0,1,0));
28+
for(int32_t p=(int32_t)x;p<e;p+=8)SetF64(p,dnorm4(F64(p),0,1,0));
3029
return x;
3130
}
3231
void rmath(void){
3332
reg(dnrm,"dnorm",1);
3433
}
35-
__attribute((section("reg")))void*rrmath=rmath;
34+
__attribute((section("rek")))void*rrmath=rmath;

k+/sparse.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
#include<suitesparse/SuiteSparseQR_C.h>
21
//umfpack solve sparse Ax=b
32
int umfpack_di_symbolic(int,int,int*,int*,double*, void**,double*,double*);
43
int umfpack_zi_symbolic(int,int,int*,int*,double*,double*,void**,double*,double*);
@@ -11,7 +10,6 @@ int umfpack_zi_solve(int,int*,int*,double*,double*,double*,double*,double*,doub
1110
void umfpack_di_free_numeric(void**);
1211
void umfpack_zi_free_numeric(void**);
1312

14-
/*
1513
//spqr sparse least squares (cholmod.h spqr.h)
1614
typedef struct choldmod_dense_struct {
1715
size_t nrow,ncol,nzmax,d; //A is nrow x ncol, nmax(entries) d(lda>=nrow)
@@ -25,8 +23,8 @@ typedef struct cholmod_sparse_struct{
2523
} cholmod_sparse;
2624
int cholmod_start(void*cc);
2725
int cholmod_finish(void*cc);
26+
int cholmod_free_dense(cholmod_dense**,void*);
2827
cholmod_dense*SuiteSparseQR_C_backslash_default(cholmod_sparse*A,cholmod_dense*B,void*cc);
29-
*/
3028

3129
uint64_t spqr(uint64_t x){ //todo: b maybe m-by-k dense..
3230
uint64_t common[400];//enough to hold cholmod_common structure (sizeof 2680)
@@ -35,20 +33,22 @@ uint64_t spqr(uint64_t x){ //todo: b maybe m-by-k dense..
3533
uint64_t M=x0(A),N=x1(A),Ap=x2(A),Ai=x3(A),Ax=FZ(x4(A));dx(A);int z=(tp(Ax)==Zt);
3634
if(tp(M)!=it||tp(N)!=it||tp(Ap)!=It||tp(Ai)!=It)trap();
3735
int32_t m=(int32_t)M,n=(int32_t)N;
38-
if(nn(B)!=m)trap();if(z&&tp(B)!=Zt)B=uptype(B,zt);
36+
if(nn(Ap)!=1+n||nn(Ai)!=nn(Ax))trap();
37+
int32_t nb=nn(B),k=nb/m;if(nb!=k*m)trap(); //k>1: multirhs flat colmajor vector
38+
if(z&&tp(B)!=Zt)B=uptype(B,zt);
3939
void *cc=&common;cholmod_start(cc);
4040
cholmod_sparse a;
41-
a.nrow=m;a.ncol=n;a.nzmax=nn(A);a.p=IK(Ap);a.i=IK(Ai);a.nz=NULL;a.x=FK(A);a.z=NULL;
41+
a.nrow=m;a.ncol=n;a.nzmax=nn(Ax);a.p=IK(Ap);a.i=IK(Ai);a.nz=NULL;a.x=FK(Ax);a.z=NULL;
4242
a.stype=0;a.itype=0;a.xtype=1+z;a.dtype=0;a.sorted=0;a.packed=1;
4343
cholmod_dense b;
44-
b.nrow=m;b.ncol=1;b.nzmax=m;b.x=FK(B);b.z=NULL;b.xtype=1+z;b.dtype=0;
44+
b.nrow=m;b.ncol=k;b.nzmax=m;b.x=FK(B);b.z=NULL;b.xtype=1+z;b.dtype=0;
4545
cholmod_dense*r=SuiteSparseQR_C_backslash_default(&a,&b,cc);
46-
//printf("r: %d %d #%d xt%d dt%d: [", r->nrow, r->ncol, r->nzmax, r->xtype, r->dtype);
47-
//printf("%g %g %g %g %g]\n", r->x[0], r->x[1], r->x[2], r->x[3], r->x[4]);
46+
dx(Ap);dx(Ai);dx(Ax);dx(B);
47+
x=mk(z?Zt:Ft,nb);
48+
memcpy(M_+(int32_t)x,r->x,nb<<(z?4:3));
49+
cholmod_free_dense(&r,cc);
4850
cholmod_finish(cc);
49-
//todo is A/B overwritten? where is the workspace, what must be freed?
50-
//cholmod_free_dense(
51-
return Ki(0);
51+
return x;
5252
}
5353

5454
//dense matrix representation
@@ -63,6 +63,7 @@ uint64_t spsolve(uint64_t x){ // spsolve[A;b]
6363
uint64_t N=x1(A),Ap=x2(A),Ai=x3(A),Ax=FZ(x4(A));dx(A);
6464
if(tp(N)!=it||tp(Ap)!=It||tp(Ai)!=It)trap();
6565
int z=0,n=(int32_t)N;int*ap=IK(Ap),*ai=IK(Ai);double*ax=FK(Ax);void*sy,*nu;
66+
if(nn(Ap)!=1+n||nn(Ai)!=nn(Ax))trap();
6667
if(tp(Ax)==Ft){
6768
if(umfpack_di_symbolic(n,n,ap,ai,ax,&sy,NULL,NULL))trap();
6869
if(umfpack_di_numeric(ap,ai,ax,sy,&nu, NULL,NULL)){umfpack_di_free_symbolic(&sy);trap();}
@@ -96,7 +97,6 @@ uint64_t spsolve(uint64_t x){ // spsolve[A;b]
9697
return mrhs?r:Fst(r);
9798
}
9899
void umfpack(void){
99-
printf("%d\n", sizeof(cholmod_common)); //2680
100100
reg(spsolve,"spsolve",2);
101101
reg(spqr, "spqr", 2);
102102
}
@@ -132,6 +132,6 @@ void *Symbolic, *Numeric ;
132132
#include<stdio.h>
133133
#include<cholmod.h>
134134
int main(){
135-
printf("%d\n", sizeof(cholmod_common)); //2680(win) 2664(debian)
135+
printf("%d\n", sizeof(cholmod_common)); //should be 2680
136136
}
137137
*/

k+/tests/sparse.t

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ b:8. 45. -3. 3. 19. /
33
r:1 2 3 4 5. /
44
1e-12>|/abs spsolve[A;b]-r /1
55
_0.5++/+/spsolve[A;(b;b;b)] /45
6-
spqr[A;b] /3
6+
1e-12>|/abs spqr[A;b]-r /1
7+
+/_0.1+spqr[A;b,b,b] /45

0 commit comments

Comments
 (0)