記事"R で 統計分布を MQL5 に -"についてのディスカッション - ページ 7

 
ivanivan_11:

私はRについて話していますが、私のスキルは非常に小さいです))誰かがコードが正しいかどうかをチェックできますか?

もしコードが正しければ、ベンチマークをチェックしてもらえますか?

コードが間違っています。

あなたが計測したのは関数のコンパイル時間であり、実行時間ではありません:

関数cmpfunはクロージャのボディをコンパイルし、同じ書式とボディをコンパイルされたボディ式に置き換えた新しいクロージャを返します。


エラーの証明

> library(microbenchmark)
> library(compiler)
> n <- 2000
> k <- seq(0,n,by=20)
> qqq<- function(xx) { a <- dbinom(k, n, pi/10, log = TRUE) }
> res <- microbenchmark(cmpfun(qqq))
> a
Ошибка: объект 'a' не найден

もしqqq関数がベンチマーク中に実行されていれば、オブジェクトaは計算されたデータを受け取るはずでした。しかし、その代わりにオブジェクトが生成されていないことが判明しました。

その結果、ベンチマークは実行時間ではなく コンパイル時間をカウントした。私のコードでは、すべてが正しい。ベンチマークは実際の実行時間をカウントし、オブジェクトaは正しいデータで作成される。


そう、コンパイルはかなりコストのかかる処理なのだ。マイクロ秒ではなくミリ秒で表示されている。

> print(res)
Unit: milliseconds
        expr      min       lq     mean   median       uq      max neval
 cmpfun(qqq) 1.741577 1.783867 1.856366 1.812613 1.853096 2.697548   100
 

また、別のジョークですが、あなたの例では、システム関数q()-quit-をどのようにオーバーライドしたのですか?

Rを終了する方法なんてなかったんだ :)

 
Dr.Trader:

つまり、mqlコンパイラはコンパイル時にすでにすべての入力パラメーターを知っているということだ。コンパイル時にすべてを計算し、スクリプトを呼び出すときには、事前に計算された結果を返すだけで十分なのだ。ハブでc++コンパイラを比較した記事をいくつか見たが、アセンブラ・コードの解析から判断すると、まさにそこで起こっていることだ。

そう、積極的に使っているのかもしれない。https://www.mql5.com/ru/forum/58241。

しかし、この場合はうまくいかない。複雑で、ループや配列が埋まってしまうので、フルカウントする必要がある。

 
ivanivan_11:

コードが正しければ、ベンチマークをチェックできますか?

res <- microbenchmark(cmpfun ( q))res <- microbenchmark(q()) に置き換える 必要があります。)しかし、以前にコンパイルされたライブラリはバイトコードに再コンパイルされません。

Renat Fatkhullin:
qqq<- function(xx) { a <- dbinom(k, n, pi/10, log = TRUE) }

この場合、"a "はローカル変数に なり、関数自体の外からはアクセスできません。しかし、このようにすることもできる
a<<- dbinom(k, n, pi/10, log = TRUE)
そうするとグローバル変数になります。

Renat Fatkhullin:

しかし、この場合はうまくいかない。ループや配列の充填が複雑になるので、完全にカウントする必要がある。

なるほど、実行速度は素晴らしいですね。

 

ところで、a <- dbinom(k, n, pi/10, log = TRUE) というプリミティブな呼び出しを、ネイティブ実行のRカーネルに直接フォールして解釈するのには、実質的に何のコストもかからない(dbinomは r.dllにある)。

ですから、この呼び出しをコンパイルしようとしても、明らかに無駄です。

 

Rの速さについては何度も書いてきたので、5セントだけ言わせてほしい。

レナトへ!

あなたの例はまったく無意味です!

あなたは似たような2つの関数を取り上げて、Rの性能について全く結論を出していません。

あなたが挙げた関数は、Rのパワーと多様性をまったく表していません。

計算量の多い演算を比較すべきです。

例えば、行列の乗算...

Rの式を測ってみよう

c <- a*b、

ここでaとbは少なくとも100*100の大きさの行列である。あなたのコードでは、RがインテルのMKLを使用していることを確認してください。これは、対応するバージョンのRをインストールするだけでよい。

Rを見ると、計算集約的な操作を含むコードが山のようにある。それらを実行するために、現時点で最も効率的なライブラリが使用される。

そして、トレーディングにおけるRの有用性は、あなたが書き直した関数にあるのではなく(それも必要ではあるが)、モデルにあるのだ。あなたへの返信の中で、私はcaretパッケージについて触れました。その内容をご覧ください。このパッケージとμlの枠組みの中で、実用的に有用なトレーディング・モデルを実装すれば、答えがわかるだろう。

その上、カンプのすべてのコアをロードすることがRのルーチンであることを忘れてはならない。さらに、ローカルネットワーク上の近隣のコンプをロードすることもできます。

追記

私にとって、MKLとRの性能を比較することには疑問がある。

 

SanSanych、我々はすべてをテストし、ベンチマークをリリースするつもりだ。しかし、まずは機能を完成させる。

テストは正当化され、すぐに問題が明らかになりました。理論的な正当性を示しましたが、圧倒的な機能量の割にRのシステム・オーバーヘッドは保たれると確信しています。

インテルが負けるような方法で行列を掛けることができる。これはとっくにロケット・サイエンスではないし、インテル(というか、そのような会社所属のサードパーティ・プログラマー)は、そのプロセッサーの神話的知識のチャンピオンではない。

 
СанСаныч Фоменко:

Rの速さについては何度も書いているので、5セントだけ言わせてほしい。

.................

サン・サニッチと他のみんなへ。

サン・サニチ、私が君をどれだけ尊敬しているか知っているだろう.(カタエフとファインツィルベルク、通称 "イルフとペトロフ")、ここでのあなたのポストソビエト・ジョークにもかかわらずね。

重要なことをはっきりさせておこう:

1).プログラマーの主な仕事はプログラムを書く ことではなく、プログラムを読むことである。どんなプログラマーでも、95...99%の時間は座ってモニターを見つめている。彼はプログラムを書くのか?いや、ほとんど読むだけだ。したがって、彼がスクリーンで読むものが自然言語に近ければ近いほど、つまり彼が母親、父親、祖母、学校の先生から教えられたものに近ければ近いほど、彼はスクリーン上の言語的に従順なクラコゼブラをより効率的に解読し、アルゴリズムと彼のプログラムとの対応関係を見つけることができる。

2).1)の目的のために、平均してC言語に勝るものはない。 だからこそ、例えば私個人は(2-3人の責任感のある人とそうでない人と同様に)700以上のサブルーチンを持つプロジェクトを C言語、MQL4、CUDA......で書くことができた。そして、すべてが機能している。

3).1)から見ると、Cのオブジェクト指向の亜種、つまりC++はもっとひどい。(しかしそれについてはまた別の機会に)。

4).古典的なC言語とMQL4の完全な互換性は非常に貴重である。プロシージャーを行ったり来たりするのに半分もかからない。

5).C+MQL4の主な利点はCLARITYである。つまり、プログラマーの画面上にあるすべてのものの理解しやすさ、透明性である。

C-MQL4とあなたのRを比較するならば、書かれたコードのスピードや量ではなく、テキストのCLARITYを見るべきである。つまりわかりやすさだ。そうでなければ、プログラマーはそのプログラムが何をするのか、どのようなパラメーターがあるのか、なぜ作者はそのような名前をつけたのか、一般的になぜプログラマーはこのような方法をとり、他の方法はとらなかったのかを理解するために、24時間画面を凝視することになる。ここで重要なのは、プログラムのスピードではなく、その動作の正確さと、最終的なプログラマーにとっての適用可能性のスピードである。

この観点から、Metaquotesが行ったことは、EAに統計を挿入したい人にとって、もちろん素晴らしいサポートである。機能のシンプルさとわかりやすさという点では、比べるものがない。そして、これは重要なことです。特にデリケートな計算をする場合(FXや取引全般でデリケートな計算が必要です)。

比較してみよう。

C言語 - MQL4では、統合関数はこのようになります:

//__________________________________________________________________
//|
// Integral_Simpson_3_Points_Lite ()|
//_______________________________________________________|
#define  FACTOR_1_3      (1.0 / 3.0)

double Integral_Simpson_3_Points_Lite
(
   double       & Price_Array[],
   int          Period_Param,
   int          Last_Bar
)
{
        double  Sum, Sum_Full_Cycles, Sum_Tail, Sum_Total;
        int             i, j;
        int             Quant;
        int             Full_Cycles;
        int             Tail_Limit;
        int             Tail_Start;

        //..................................................................
        if (Last_Bar < 0)
        {
                Last_Bar = 0;
        }
        //.........................................
        if (Period_Param <= 1)
        {
                return (0.0);
        }
        //.................................................................
        if (Period_Param == 2)
        {
                return (0.5 * (Price_Array[Last_Bar] + Price_Array[Last_Bar + 1]));
        }
        //=============================================================================================
        //=============================================================================================
        Quant = 3;
        Full_Cycles = (Period_Param - 1) / (Quant - 1);
        Tail_Start = Full_Cycles * (Quant - 1);
        Tail_Limit = Period_Param - Tail_Start;
        //...........................................................
        j = Last_Bar;

        Sum = 0.0;
        for (i = 0; i < Full_Cycles; i ++)
        {
                //.........................................................................
                Sum += Price_Array[j];
                Sum += 4.0 * Price_Array[j + 1];
                Sum += Price_Array[j + 2];
                j = j + (Quant - 1);
        }
        //...........................................................
        Sum_Full_Cycles = Sum * FACTOR_1_3;
        Sum_Tail = Integral_Trapezoid_Lite (Price_Array,
                                            Tail_Limit,
                                            Last_Bar + Tail_Start);
        //.........................................................................
        Sum_Total = Sum_Full_Cycles + Sum_Tail;
        //...............................................................
        return (Sum_Total) ;

}
 

その方が書きやすいので、部分的に書きます。

中に台形積分関数がある:

//__________________________________________________________________
//|
// Integral_Trapezoid_Lite ()|
//_______________________________________________________|
double Integral_Trapezoid_Lite
(
   double       & Price_Array[],
   int          Period_Param,
   int          Last_Bar
)
{
        double  Sum;
        int             i;
        int             Price_Index ;
        //.........................................
        if (Last_Bar < 0)
        {
                Last_Bar = 0;
        }
        //.........................................
        if (Period_Param <= 1)
        {
                return (0.0);
        }
        //.................................................................
        if (Period_Param == 2)
        {
                return (0.5 * (Price_Array[Last_Bar] + Price_Array[Last_Bar + 1]));
        }
        //..................................................................
        //..................................................................
        Sum = 0.0;
        for (i = 0; i < Period_Param; i++)
        {
                Price_Index = Last_Bar + i;
                if (Price_Index < 0)
                {
                        break;
                }
                //........................................
                if ((i == 0) || (i == (Period_Param - 1)))
                {
                        Sum = Sum + Price_Array[i] * 0.5;
                }
                else
                {
                        Sum = Sum + Price_Array[i];
                }
        }
        //...............................................................
        return (Sum) ;
}
 

すべてが明確でわかりやすい。そして重要なことは、MT4-MQL4であっても、常に動作し、うまく機能すること、つまりエラーが少ないことで、多くの時間を節約できることです。

しかし、Rで作業しているときに理解できないエラーが発生する理由を知りたい場合、あるいは統合プロシージャにどのようなパラメータがあるのか、あるいはどのような統合方法がプログラムされているのかを理解したい場合は、以下をご覧ください(未熟なプログラミング・キッズのために投稿したことをお許しください):

http://www.netlib.org/quadpack/

これはもともとFortranで書かれた関数のタイトルだけである。本文は後ほど。これは、Rパッケージで統合のために使われているオリジナルのプログラムである。

ここで何を理解すればいいのだろう?

      subroutine qagse(f,a,b,epsabs,epsrel,limit,result,abserr,neval,
     *   ier,alist,blist,rlist,elist,iord,last)
c***begin prologue  qagse
c***date written   800101   (yymmdd)
c***revision date  830518   (yymmdd)
c***category no.  h2a1a1
c***keywords  automatic integrator, general-purpose,
c             (end point) singularities, extrapolation,
c             globally adaptive
c***author  piessens,robert,appl. math. & progr. div. - k.u.leuven
c           de doncker,elise,appl. math. & progr. div. - k.u.leuven
c***purpose  the routine calculates an approximation result to a given
c            definite integral i = integral of f over (a,b),
c            hopefully satisfying following claim for accuracy
c            abs(i-result).le.max(epsabs,epsrel*abs(i)).
c***description
c
c        computation of a definite integral
c        standard fortran subroutine
c        real version
c
c        parameters
c         on entry
c            f      - real
c                     function subprogram defining the integrand
c                     function f(x). the actual name for f needs to be
c                     declared e x t e r n a l in the driver program.
c
c            a      - real
c                     lower limit of integration
c
c            b      - real
c                     upper limit of integration
c
c            epsabs - real
c                     absolute accuracy requested
c            epsrel - real
c                     relative accuracy requested
c                     if  epsabs.le.0
c                     and epsrel.lt.max(50*rel.mach.acc.,0.5 d-28),
c                     the routine will end with ier = 6.
c
c            limit  - integer
c                     gives an upperbound on the number of subintervals
c                     in the partition of (a,b)
c
c         on return
c            result - real
c                     approximation to the integral
c
c            abserr - real
c                     estimate of the modulus of the absolute error,
c                     which should equal or exceed abs(i-result)
c
c            neval  - integer
c                     number of integrand evaluations
c
c            ier    - integer
c                     ier = 0 normal and reliable termination of the
c                             routine. it is assumed that the requested
c                             accuracy has been achieved.
c                     ier.gt.0 abnormal termination of the routine
c                             the estimates for integral and error are
c                             less reliable. it is assumed that the
c                             requested accuracy has not been achieved.
c            error messages
c                         = 1 maximum number of subdivisions allowed
c                             has been achieved. one can allow more sub-
c                             divisions by increasing the value of limit
c                             (and taking the according dimension
c                             adjustments into account). however, if
c                             this yields no improvement it is advised
c                             to analyze the integrand in order to
c                             determine the integration difficulties. if
c                             the position of a local difficulty can be
c                             determined (e.g. singularity,
c                             discontinuity within the interval) one
c                             will probably gain from splitting up the
c                             interval at this point and calling the
c                             integrator on the subranges. if possible,
c                             an appropriate special-purpose integrator
c                             should be used, which is designed for
c                             handling the type of difficulty involved.
c                         = 2 the occurrence of roundoff error is detec-
c                             ted, which prevents the requested
c                             tolerance from being achieved.
c                             the error may be under-estimated.
c                         = 3 extremely bad integrand behaviour
c                             occurs at some points of the integration
c                             interval.
c                         = 4 the algorithm does not converge.
c                             roundoff error is detected in the
c                             extrapolation table.
c                             it is presumed that the requested
c                             tolerance cannot be achieved, and that the
c                             returned result is the best which can be
c                             obtained.
c                         = 5 the integral is probably divergent, or
c                             slowly convergent. it must be noted that
c                             divergence can occur with any other value
c                             of ier.
c                         = 6 the input is invalid, because
c                             epsabs.le.0 and
c                             epsrel.lt.max(50*rel.mach.acc.,0.5 d-28).
c                             result, abserr, neval, last, rlist(1),
c                             iord(1) and elist(1) are set to zero.
c                             alist(1) and blist(1) are set to a and b
c                             respectively.
c
c            alist  - real
c                     vector of dimension at least limit, the first
c                      last  elements of which are the left end points
c                     of the subintervals in the partition of the
c                     given integration range (a,b)
c
c            blist  - real
c                     vector of dimension at least limit, the first
c                      last  elements of which are the right end points
c                     of the subintervals in the partition of the given
c                     integration range (a,b)
c
c            rlist  - real
c                     vector of dimension at least limit, the first
c                      last  elements of which are the integral
c                     approximations on the subintervals
c
c            elist  - real
c                     vector of dimension at least limit, the first
c                      last  elements of which are the moduli of the
c                     absolute error estimates on the subintervals
c
c            iord   - integer
c                     vector of dimension at least limit, the first k
c                     elements of which are pointers to the
c                     error estimates over the subintervals,
c                     such that elist(iord(1)), ..., elist(iord(k))
c                     form a decreasing sequence, with k = last
c                     if last.le.(limit/2+2), and k = limit+1-last
c                     otherwise
c
c            last   - integer
c                     number of subintervals actually produced in the
c                     subdivision process
c
c***references  (none)
c***routines called  qelg,qk21,qpsrt,r1mach
c***end prologue  qagse
c
      real a,abseps,abserr,alist,area,area1,area12,area2,a1,
     *  a2,b,blist,b1,b2,correc,defabs,defab1,defab2,r1mach,
     *  dres,elist,epmach,epsabs,epsrel,erlarg,erlast,errbnd,
     *  errmax,error1,error2,erro12,errsum,ertest,f,oflow,resabs,
     *  reseps,result,res3la,rlist,rlist2,small,uflow
      integer id,ier,ierro,iord,iroff1,iroff2,iroff3,jupbnd,k,ksgn,
     *  ktmin,last,limit,maxerr,neval,nres,nrmax,numrl2
      logical extrap,noext
c
      dimension alist(limit),blist(limit),elist(limit),iord(limit),
     * res3la(3),rlist(limit),rlist2(52)
c
      external f
c
c            the dimension of rlist2 is determined by the value of
c            limexp in subroutine qelg (rlist2 should be of dimension
c            (limexp+2) at least).
c
c            list of major variables
c            -----------------------
c
c           alist     - list of left end points of all subintervals
c                       considered up to now
c           blist     - list of right end points of all subintervals
c                       considered up to now
c           rlist(i)  - approximation to the integral over
c                       (alist(i),blist(i))
c           rlist2    - array of dimension at least limexp+2
c                       containing the part of the epsilon table
c                       which is still needed for further computations
c           elist(i)  - error estimate applying to rlist(i)
c           maxerr    - pointer to the interval with largest error
c                       estimate
c           errmax    - elist(maxerr)
c           erlast    - error on the interval currently subdivided
c                       (before that subdivision has taken place)
c           area      - sum of the integrals over the subintervals
c           errsum    - sum of the errors over the subintervals
c           errbnd    - requested accuracy max(epsabs,epsrel*
c                       abs(result))
c           *****1    - variable for the left interval
c           *****2    - variable for the right interval
c           last      - index for subdivision
c           nres      - number of calls to the extrapolation routine
c           numrl2    - number of elements currently in rlist2. if an
c                       appropriate approximation to the compounded
c                       integral has been obtained it is put in
c                       rlist2(numrl2) after numrl2 has been increased
c                       by one.
c           small     - length of the smallest interval considered
c                       up to now, multiplied by 1.5
c           erlarg    - sum of the errors over the intervals larger
c                       than the smallest interval considered up to now
c           extrap    - logical variable denoting that the routine
c                       is attempting to perform extrapolation
c                       i.e. before subdividing the smallest interval
c                       we try to decrease the value of erlarg.
c           noext     - logical variable denoting that extrapolation
c                       is no longer allowed (true value)
c
c            machine dependent constants
c            ---------------------------
c
c           epmach is the largest relative spacing.
c           uflow is the smallest positive magnitude.
c           oflow is the largest positive magnitude.
c
c***first executable statement  qagse
      epmach = r1mach(4)
c
c            test on validity of parameters
c            ------------------------------