SUBROUTINE LBFGS(N,M,X,F,G,DIAGCO,DIAG,IPRINT,EPS,XTOL,W,IFLAG)
C
      INTEGER N,M,IPRINT(2),IFLAG
      DOUBLE PRECISION X(N),G(N),DIAG(N),W(N*(2*M+1)+2*M)
      DOUBLE PRECISION F,EPS,XTOL
      LOGICAL DIAGCO


'lbfgs64.dll lbfgs_ + i * * * * * * * * * * * *' cd
(100;5;(200$0);1;(200$0);0;(200$0);0 0;1e_5;1e_16;(200$0);0)

here the * in signature meant memory  address of argument , but you
provided the data itself. therefore it was mismatched and J complained.

since arguments in fortran subroutine are always passed by reference, you
cannot pass any scalar to it, because it means passed by value. instead you
should pass them as arrays where the memory address of arrays will be
passed to fortran. you also need to provide the correct signature for each
argument.
I'm not so sure what data type for fortran integer and logical, I just
assume they are 32-bit integer, then you can try something like this.

dz=. -~1.5
'lbfgs64.dll lbfgs_ + i *i *i *d *d *d *i *d *i *d *d *d *i' cd
((,100);(,5);(200$dz);(,dz);(200$dz);(,2-2);(20
0$dz);(2$2-2);(,1e_5);(,1e_16);(200$dz);,2-2)

or you can use ,&.> coerce every scalar to array.

On May 7, 2018 12:58 AM, <[email protected]> wrote:

Thank you, that helped a great deal. My update:

Downloaded Dependency Walker: http://www.dependencywalker.com/

Determined that my gfortran was compiling in x86 not 64, so needed to fix
this.

Downloaded 64 bit Mingw64, chose POSIX threads and seh:
mingw-w64\x86_64-7.3.0-posix-seh-rt_v5-rev0

Re-ran and noticed that gfortran compiled a DLL which needed IEShims

Copied IEShims from Program Files > Internet Explorer into the same folder
(J bin folder)

Recompiled from c:\MinGW\test\:
"c:\Program
Files\mingw-w64\x86_64-7.3.0-posix-seh-rt_v5-rev0\ming64\bin\gfortran.exe"
-c lbfgs.f
"c:\Program
Files\mingw-w64\x86_64-7.3.0-posix-seh-rt_v5-rev0\ming64\bin\gfortran.exe"
-shared -o lbfgs64.dll lbfgs.o

Dependency Walker showed that numerous DLL's from gfortran were needed:

Copied to J folder:
lbfgs64.dll
libgcc_s_seh-1.dll
libgfortran-4.dll
libquadmath-0.dll
libwinpthread-1.dll

fexist 'lbfgs64.dll'
1

First attempt:

'lbfgs64.dll lbfgs_ + i * * * * * * * * * * * *' cd
(100;5;(200$0);1;(200$0);0;(200$0);0 0;1e_5;1e_16;(200$0);0)
|domain error: cd
|   'lbfgs64.dll lbfgs_ + i * * * * * * * * * * * *'
cd(100;5;(200$0);1;(200$0);0;(200$0);0 0;1e_5;1e_16;(200$0);0)
|[-0]
   cder''
6 0

So this time it worked in the sense that it called the Fortran code, but
was called with the wrong type - error 6 0 says wrong parameter type for
first variable.

I tried to fix this, using the code sample I found below, and it seems to
be calling the Fortran code now, even if only kicks out an error (the
parameters don't seem to be right).

So, still doesn’t work, but getting a lot closer to working.

---


load '~addons/math/lbfgs/lbfgs.ijs'
NB.===========================================================
NB.
NB. Von Bertalanfy fit using LBFGS optimizatin
NB. outputs stats matrix & parm vector
NB. solution with EXCEL's SOLVER is linf = 55.9778, k = 0.385595, t0 =
0.171371
NB.
NB.========================================================================
NB. INPUTS
years  =: 1.0 2.0 3.3 4.3 5.3 6.3 7.3 8.3 9.3 10.3 11.3
length  =: 15.4 26.93 42.23 44.59 47.63 49.67 50.87 52.3 54.77 56.43 55.88
initial  =: 30.0 0.20 0.01
NB.=======================================================================
VON_B =: 3 : 0
'a b c' =. y
l_pred =. a * (1 -^ - (b * years - c))
rss  =. e +/ .* e =. length - l_pred
n2  =: ($years)%2
NB. sd  =: %: var =: rss%$e
NB. (($years)%2)*((^.(o.2))+(2*^.sd) +1)
NB. (($years)%2)*((^.(o.2))+(^.var) +1)
NB. (n2*(^.rss))-(n2*^.$years)-(n2*(^.o.2))+n2
NB. (n2*(^.var))+(n2*(^.o.2))+n2
n2*(^.rss)
)
NB.========================================================================
DERIVLOGL =: 3 : 0
epsd   =:  1e_5
f0    =: OBJ_FN y
grad   =: 0$0
for_i. i.#y do.
  yy   =: (epsd+i{y) i } y
  f1   =: OBJ_FN yy
  yyy  =:((-epsd)+i{y) i } y
  f2   =: OBJ_FN yyy
  grad   =: grad,(f1-f2)%+:epsd
end.
)

LBFGS  =: 4 : 0
OBJ_FN  =: (<x)`:6
n   =: $parm =: y       NB. length n; number of parameters
m   =: 5         NB. length 1; number of corrections used in BFGS update.
Should be between 3 and 7
diagco  =:  2-2         NB. length 1; Logical variable; set at 0; if 1.0,
need to provide diagonal matrix
diag  =: n$2.2-2.2       NB. length n$0; provide double array if diagco 1
iprint  =:  2 2-2 2        NB. length 2; only 0 0 implemented
eps   =:  1.0e_5        NB. Accuracy of solution: grad < eps (max of
1,fun_parm)
machine  =:  1.0e_16        NB. estimate of machine presision
w   =:  (n*(2*m+1)+2*m) $ 2.2-2.2   NB. workspace size for LBFGS
iflag  =:  2-2         NB. initially set to 0; codes which indicate
performance of routine
niter  =: 0

while. niter <: 1000 do.
fun_parm  =:  OBJ_FN parm       NB. Value of objective function at parm
grad =: ((0.00001*parm) + (0.00000001*parm = 0)) OBJ_FN D: 1 parm  NB.
length n; gradient of objective function at parm
NB. grad  =.  DERIVLOGL parm
'n m parm fun_parm grad diagco diag iprint eps machine w
iflag'=.r=:'lbfgs_' call
(n;m;parm;fun_parm;grad;diagco;diag;iprint;eps;machine;w;iflag)
 if. iflag <: 0 do. break. end.
 output  =: niter, ; 3 2 4{r NB. iter, value, point, grad
niter  =: >: niter
end.
)

'VON_B' LBFGS initial

outres =: 'lbfgs64.dll lbfgs_ + i  * * * * * * * * * * * *' cd LASTIN
'other n m parm fun_parm grad diagco diag iprint eps machine w iflag' =.
outres




-----Original Message-----
From: Programming <[email protected]> On Behalf Of
bill lam
Sent: Sunday, May 06, 2018 10:35 AM
To: [email protected]
Subject: Re: [Jprogramming] Getting LBFGS back online

I think some dependency dll for lbfgs.dll are missing. Is some runtime
library needed?  One way to check to use dependency walker.

I assume you had built the 64-bit version.

Вс, 06 мая 2018, [email protected] написал(а):
> It seems that some time ago in j601, LBFGS was included in the J tree
> (http://code.jsoftware.com/wiki/JAL/j601), but is now no longer
> included. So I've been trying to get it back and functional on Windows
> again, with no success. Here's what I've tried:
>
>
>
> Download L-BFGS Fortran source code:
> https://github.com/lawrennd/ndlutil/blob/master/src/lbfgs.f
>
> Compile Fortran code: gfortran -c lbfgs.f
>
> Compile to DLL: gfortran -shared -o lbfgs.dll lbfgs.o
>
> Copy DLL to J directory: C:\Program Files\j64-805\bin
>
>
>
> The file appears to exist to J:
>
>
>
> fexist 'lbfgs.dll'
>
> 1
>
>
>
> However, this does not work (although it should, as it's taken from
> prior
> examples):
>
>
>
> 'lbfgs.dll lbfgs_ + i * * * * * * * * * * * *' cd
> (100;5;(200$0);1;(200$0);0;(200$0);0 0;1e_5;1e_16;(200$0);0)
>
> |domain error: cd
>
> | 'lbfgs.dll lbfgs_ + i * * * * * * * * * * * *'
> cd(100;5;(200$0);1;(200$0);0;(200$0);0 0;1e_5;1e_16;(200$0);0)
>
> |[-0]
>
>
>
> cder''
>
> 1 0
>
>
>
> According to this
> (http://code.jsoftware.com/wiki/Guides/DLLs/Error_Messages) page,
> result 1 0 means "file not found".
>
>
>
> That doesn't seem right. I must be missing something. help?
>
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm

--
regards,
====================================================
GPG key 1024D/4434BAB3 2008-08-24
gpg --keyserver subkeys.pgp.net --recv-keys 4434BAB3 gpg --keyserver
subkeys.pgp.net --armor --export 4434BAB3
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to