I worked more on this and the code below seems to do things
Instead of my own numerical derivatives I let J itself provide
the derivatives (this seems to work well on situations I have tried),
Anyway below "minl" is an adverb which when applied to
function F and given a starting value for the function, X, returns
the the minimum, minimizer and partial derivatives at the minimum, as
well as the number of iterations.

minl=: 1 : 0   NB.  lbfgs minimization
  f=.u
  N=.#X=:2.2+(,y)-2.2  NB. ensures X is real
  M=.5                 NB. number of corrections
  'DIAGCO IFLAG'=.2-2  NB. logical set to 0=false
  DIAG=.N$2.2-2.2      NB. real set to 0
  IPRINT=.2 2-2 2      NB. integer: only 0 0 permitted
  'EPS XTOL'=.1.0e_5 1.0e_16    NB. real epsilon and tolerance
  W=.((N*(>:+:M))++:M)$2.2-2.2  NB. real work vector
  iter=.0
  whilst. (IFLAG>0)*.(iter<:2000) do. iter=.>:iter
    'F G'=. (f;f D. 1) X   NB. function and derivative value
    'N M X F G DIAGCO DIAG IPRINT EPS XTOL W IFLAG'=.'lbfgs_' call
(N;M;X;F;G;DIAGCO;DIAG;IPRINT;EPS;XTOL;W;IFLAG)
  end.
  F;X;G;iter
)

The "call" is as is in the lbfgs addon package.



On Thu, Apr 8, 2010 at 6:17 PM, Piet de Jong <[email protected]> wrote:
> Thanks for looking at this.
> What confused me was the "larger" dimension on X etc
> For example the code working off
> NDIM=. 2000
>
> Anyway after a lot of fiddling I seem to have it working at least with
> simple examples,
> including with the use of  numerical rather than exact derivatives.
> Here is my "test" case
> using N=4 with the sum of squares function centered on an (arbitrary) origin.
>
> NB.  Df is exact derivative, while Dfh is numerical derivative using h
>
> mtr=: 3 : 0   NB.  lbfgs test
>  'N M'=.4 5           NB. dimension of X, number of corrections
>  f=.+/@:*:@:-&3 _2002 800 1 NB. example sum of squares  function
>
>  Df=.f D. 1           NB. exact derivative
>  h=.1.0e_8            NB. h for numerical derivative
>  H=.(h&*)@=...@i.@#      NB. diag h
>  Dfh=.-:@(%&h)@:((+(-&f)-)H) NB. numerical derivative
>
>  'DIAGCO IFLAG'=.2-2  NB. logical set to 0=false
>  DIAG=.N$2.2-2.2      NB. real set to 0
>  IPRINT=.2 2-2 2      NB. integer: only 0 0 permitted
>  'EPS XTOL'=.1.0e_5 1.0e_16    NB. real epsilon and tolerance
>  W=.((N*(>:+:M))++:M)$2.2-2.2  NB. real work vector
>
>  X=.N$400.2-2.2      NB. initialize X
>  iter=.0             NB. initialize iter
>  whilst. (IFLAG>0)*.(iter<:2000) do. iter=.>:iter
>    'F G'=. (f;Dfh) X   NB. funtion and derivative value -- use Dfh
> for numerical derivative
>    'N M X F G DIAGCO DIAG IPRINT EPS XTOL W IFLAG'=.'lbfgs_' call
> (N;M;X;F;G;DIAGCO;DIAG;IPRINT;EPS;XTOL;W;IFLAG)
>  end.
>  iter;(f;])X
> )
>
>
>
>
>
> On Thu, Apr 8, 2010 at 7:08 AM, Raul Miller <[email protected]> wrote:
>> On Wed, Apr 7, 2010 at 4:38 PM, Piet de Jong <[email protected]> wrote:
>>> Thanks for the response.   I downloaded the routine using the package 
>>> manager
>>> and J6.02.
>>>
>>> What I don't get is that the in the example lbfgs_test the routine is
>>> called with parameter
>>> values that do not correspond to what is stated in the provided
>>> FORTRAN description of the calling sequence.
>>
>> So... looking at math/lbfgs, I see:
>> path=: jpath '~addons\math\lbfgs\'
>> dll=:'"',path,'lbfgs.dll" '
>> ...
>> call=: 4 : 0
>> xx=. dll,x,' + i ',(+:#y)$' *'
>> r=. xx cd LASTIN=: , each y
>> ...
>>
>> and, I see:
>>
>> 'N M X F G DIAGCO DIAG IPRINT EPS XTOL W IFLAG'=.r=.'lbfgs_' call
>> (N;M;X;F;G;DIAGCO;DIAG;IPRINT;EPS;XTOL;W;IFLAG)
>>
>> So that means that the calling signature will be
>>
>>  "...lbfgs.dll" lbfgs_ + i * * * * * * * * * * * *
>>
>> According to http://www.jsoftware.com/help/user/call_procedure.htm
>> this means that under windows this routine uses the __cdecl calling
>> convention, returns a 4 byte integer result and takes 12 pointers as
>> arguments.
>>
>> I modified lbfgs_test to capture the data being passed to "call" and
>> when I interrupted the program the values were all one dimension
>> arrays, with dimensions:
>> N: 1
>> M: 1
>> X: 2000
>> F: 1
>> G: 2000
>> DIAGCO: 1
>> DIAG: 2000
>> IPRINT: 2
>> EPS: 1
>> XTOL: 1
>> W: 60000
>> IFLAG: 1
>>
>> Now... I do not know how lbfgs works, and I do not know
>> if there is some windows magic that happens to pass the
>> size of these arrays in a __cdecl call, or if the pointers to
>> these values are treated as pointers regions of memory where
>> extra values off the end would be ignored.
>>
>> But it very much looks like this code is directly calling
>> lbfgs.dll and not doing much of any thing special to
>> the data on its way out.
>>
>>> In particular and as an example, the dimension on X does not appear to
>>> be N but something much bigger.   Hence the example is hard, if not
>>> impossible to follow.   It might be useful to have a much simpler
>>> example.   I still can't get a simple example to work since I don't
>>> appear to understand the calling parameters.
>>
>> My current best guess is that (if N is supposed to be the
>> number of elements provided by X), values after the first 100 (the
>> value for N) are ignored by lbfgs.dll.
>>
>> Do you see anything which would contradict this point of view?
>>
>> Thanks,
>>
>> --
>> Raul
>> ----------------------------------------------------------------------
>> For information about J forums see http://www.jsoftware.com/forums.htm
>>
>
>
>
> --
> Piet de Jong
> --------------------------------------------------
> View my current research at
> http://ssrn.com/author=619154
> --------------------------------------------------
>



-- 
Piet de Jong
--------------------------------------------------
View my current research at
http://ssrn.com/author=619154
--------------------------------------------------
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to