2

バックグラウンド

カーン アカデミーの練習問題を書こうとしています。彼らのコードはすべてhttps://github.com/Khan/khan-exercisesから入手できます。実際に何かをプログラミングするのはこれが初めてで、基本的にサンプルコードを見るだけでhtmlとjsを学んでいます。

この演習の一環として、「ランダム関数」を描画し、それがゼロであることを確認する必要があります。ゼロ検出アルゴリズムを作成しました (ゼロを拡大するために間隔を繰り返し半分にカットします)。ニュートン法のいくつかの変形がおそらくより高速であることは知っていますが、収束を保証したかったのです。私の「ランダム関数」は一連のポイント値を取り、それらのポイントを多項式スプラインで補間します。これらはそれぞれ独立して機能します。「ランダム関数」をグラフ化し、ゼロ検出アルゴリズムを使用して、たとえば、2 の平方根 (間隔 (1,2) での x^2 - 2 のゼロ) を近似できます。「ランダム関数」のゼロを見つけようとすると、問題が発生します。ブラウザが無限ループか何かに陥ります。開発者ツールでエラーが何であるかさえわかりません。

したがって、私の質問は基本的に次のとおりです。

  1. ここで非常に多くの計算能力を消費している私が犯した間違いは何ですか?
  2. 機能が独立して機能するのに、一緒に機能しないのはどうしてでしょうか?
  3. コードを修正するにはどうすればよいですか?

私は knhan アカデミーのフレームワーク全体で作業しているため、関連するすべてのコードを投稿するにはプログラムが多すぎます (Raphael を使用して画像を処理し、演習をすべて同じスタイルにするために事前にコードを記述しているなど)。私が書いた html コードと、私が書いた関数の .js ファイルを提供できます。

<!DOCTYPE html>
<html data-require="math graphie graphie-helpers steveMath8">
  <head>
      <title>Piecewise-defined function</title>
      <script src="../khan-exercise.js"></script>
  </head>
  <body>
      <div class="exercise">
          <div class="vars">


  <var id = "n">randRange(2,4)</var>
  <var id = "abscissas">makeXList()</var>
  <var id = "ordinates">makeYList(-8,8,abscissas.length)</var>
  <var id = "points">makeCoordinates(abscissas,ordinates)</var>
 <var id = "f">(function(x){return niceFunction(x,points)})</var>
 <!-- <var id = "f">(function(x){return x*x-n})</var>-->
 <var id = zeros>locateZeros(f,abscissas)</var>





          </div>

          <div class="problems">
              <div id="problem-type-or-description">
                  <p class="problem">You are going to have to answer 5</p>
                  <p class="question">Answer 5</p>
                  <div class="graphie" id="grid">
                graphInit({
                    range: 10,
                    scale: 20,
                    tickStep: 1,
                    axisArrows: "<->"
                });

            a =style({
                        stroke: "red",
                         strokeWidth: 2
                    }, function() {
                        plot( function( x ) { return niceFunction(x,points);
                        }, [ -10, 10 ] );
                    });;
            a.plot();
            </div>

                  <p class="solution">5</p>
              </div>



          </div>

          <div class="hints">
              <!-- Any hints to show to the student. -->
          </div>
      </div>
  </body>

$.extend(KhanUtil, {

//takes num and returns +1 if num>0 or -1 if num<0
steveSign: function(num){
    return num && num/Math.abs(num)
},

// Approximates a root of f on the interval (xmin,xmax) by successively halving the   interval.
steveRoot: function(f,xmin,xmax){
    var l = xmin
    var r = xmax
    var z = 0
    for (i=0;i<10;i++){
        z = (l + r)/2
        if (KhanUtil.steveSign(f(l)) == KhanUtil.steveSign(f(z))){ l = z}
        else{r = z}   

    }
    return z
},

//takes a function and a list of abscissas, and returns an array of zeros - one zero between each pair of abscissas that are of
//opposite sign
locateZeros: function(f,abscissas){
    var len = abscissas.length
    var list = []
    var z = 0

    for(i=0;i<len-1;i++){
       var x0 = abscissas[i]
       var x1 = abscissas[i+1]
       var y0 = f(x0)
       var y1 = f(y0)

       if (KhanUtil.steveSign(y0) !== KhanUtil.steveSign(y1)){
           z = KhanUtil.steveRoot(f,x0,x1)
           list.push(KhanUtil.steveSign(f(x0)))
       }

    }
    return list
},

    steveCubic: function(x){return -Math.pow(x,3)/2+3*x/2},

//niceFunction is a C^1 function which connects the points in "points".  It is designed to be used 
//in my "curveSketchingIntuition" exercise.  Every point in the "points" will have 0 slope, except the first and last point.
niceFunction: function(x,points){

    len = points.length

    var x1 = points[0][0]
    var x2 = points[1][0]
    var y1 = points[0][1]
    var y2 = points[1][1]
    var k = (y1 - y2)/Math.pow(x1-x2,2)

    if (x<x2){return k*Math.pow(x-x2,2)+y2}

    for (i=1;i<len-2;i++){
        var x1 = points[i][0]
        var x2 = points[i+1][0]
        var y1 = points[i][1]
        var y2 = points[i+1][1]

        xNew = (x-x1)*2/(x2-x1)-1
        yNew = (KhanUtil.steveCubic(xNew)+1)*(y2-y1)/2+y1
        if (x>=x1 && x<x2){return yNew}

        }


    var x1 = points[len-2][0]
    var x2 = points[len-1][0]
    var y1 = points[len-2][1]
    var y2 = points[len-1][1]
    var k = (y2 - y1)/Math.pow(x1-x2,2)
    if (x>=x1){return k*Math.pow(x-x1,2)+y1}

},

makeXList: function(){
array = [-10]
i=0
while(array[i]<10){
    x = array[i]+3*KhanUtil.randRange(1,3)
    if (x<10){array.push(x)}
    i=i+1
    }
array.push(10)
return array

},

makeYList:function(min,max,n){
    excluded = [0]
    array = [KhanUtil.randRangeExclude(min,max,excluded)]
    excluded.push(array[0])
    array.push[KhanUtil.randRangeExclude(min,max,excluded)]
    excluded = [0]
    for (i=1;i<n;i++){
        if (array[i-2]<array[i-1]){
            array.push(KhanUtil.randRangeExclude(min,array[i-1]-1,excluded))
            }
        else{array.push(KhanUtil.randRangeExclude(array[i-1]+1,max,excluded))}
        }

    return array

},

    makeCoordinates:  function(array1,array2){
    array = []
    for (i=0;i<array1.length;i++){
        array.push([array1[i],array2[i]])
    }
    return array
},
});
4

2 に答える 2

2

ここであなたのwhileループに関係していると思います:

makeXList: function(){
array = [-10]
i=0
while(array[i]<10){
    x = array[i]+3*KhanUtil.randRange(1,3)
    if (x<10){array.push(x)}
    i=i+1
    }
array.push(10)
return array

},

常にインクリメントしていますが、常にi新しい値を配列にプッシュしているわけではないことに注意してください。xが 10 より大きい場合、インクリメントしますiが、そこには要素がなく、おそらくそれが無限ループの原因です。

于 2012-08-14T19:58:38.967 に答える
1

コードを修正しました。問題は、両方の関数で、次のようなforループがあったことです。

for(i=0;i=10;i++)

私はそれをに変更しました

for(var i=0;i=10;i++)

どうやら私のプログラムはiをグローバル変数として扱っていたので、2つの相互作用する関数は両方とも同じiをインクリメントしていました。これは意味がありますか?プログラミング言語にあるのはかなりお粗末な機能のようです。ここに何か足りないものがありますか?

于 2012-08-15T16:39:48.473 に答える