32452
R言語の外積演算関数 `outer()`を利用してガウス核関数の３次元の図の作図を行なおうとしているのですが、`outer()`関数呼び出し後の自作関数
`GaussianKernel()`の挙動が理解できずエラーが発生してしまいます。その結果scatterplot3dパッケージの３次元作図関数`scatterplot3d()`でもエラーが発生してしまいます。  
このRコードでの`outer()`関数、及び`scatterplot3d()`の挙動、及び対策案を教えて頂きたく存じますm(__)m

以下、実装中のRコードです。

```

    library( MASS )    # MASS package
    library( kernlab ) # 
    library( scatterplot3d )  # scatterplot3d関数を使用
    
    #########################
    # set gauss kernel
    #########################
    #---------------------------------------------------------------
    # GaussianKernel()
    # [in]
    #  x1 :       [vector] input data x1-axis
    #  x2 :       [vector] input data x2-axis
    #  alpha :    [scaler] constant value
    #  mean :     [vector] mean vector
    #  matSigma : [matrix] covariance matrix
    # [out]
    #  gauss :    [scaler] function value (z value)
    #---------------------------------------------------------------
    GaussianKernel <- function( x1, x2, alpha, mean, matSigma )
    {
      datX <- c(x1,x2)
      datX <- as.matrix( datX )
      mean <- as.matrix( mean )
    #print(datX)
    #print(mean)
      gauss <- ( solve( matSigma ) %*% ( datX - mean ) )
    #print(gauss)  
      gauss <- ( -alpha*t( datX-mean )%*%gauss ) 
      gauss <- exp( gauss )
    
      return( gauss )
    }
    
    lstGKernel <- list(
      x1 = seq( from=0, to=10, by=0.1 ),
      x2 = seq( from=0, to=10, by=0.1 ),
      z = matrix( 0, nrow = 100, ncol = 100 ),
      
      dat_alpha = 0.005,
      vec_u = c( -7.61,0.22 ),
      matS = matrix( c(0.72,-0.53,-0.53,0.84), nrow = 2, ncol = 2 )
    )
    
```

**このコード呼び出し後の動作が理解できていません。**

```

    # outer()で自作関数GaussianKernel()のz軸成分を求める
    lstGKernel$z <- outer( 
        lstGKernel$x1, lstGKernel$x2,                      #関数の入力データ引数x1,x2
        GaussianKernel,                                          #対象の自作関数
        lstGKernel$dat_alpha, lstGKernel$vec_u ,lstGKernel$matS  #関数の引数指定
    )
    
```

実行結果

> Error in datX - mean : non-conformable arrays
```

    ############################
    # Draw figure              #
    ############################
    scatterplot3d(
      x = lstGKernel$x1, y = lstGKernel$x2, z =lstGKernel$z,
      main = lstAxis$mainTitle,
    #  xlim=lstAxis$xlim, ylim=lstAxis$ylim, zlim = lstAxis$zlim,
      highlight = TRUE
    )
    
```

実行結果

> Error in xyz.coords(x = x, y = y, z = z, xlab = xlabel, ylab = ylabel,  
>  : 'x', 'y' and 'z' lengths differ

＜17/02/09 追記＞  
回答で提示して頂いたコードを元に作図した結果を載せておきます。

①全体図  
[![全体図](https://i.stack.imgur.com/oH1KQ.png)](https://i.stack.imgur.com/oH1KQ.png)

②x1=x2ラインの輪切り  
[![x1=x2ラインの輪切り](https://i.stack.imgur.com/yfQe8.png)](https://i.stack.imgur.com/yfQe8.png)

③特定の範囲  
[![特定の範囲](https://i.stack.imgur.com/YsRT5.png)](https://i.stack.imgur.com/YsRT5.png)
CC BY-SA 3.0
2017-02-04T13:05:37.570
32385
2017-02-09T11:12:48.160
2020-06-17T08:14:45.997
-1
20266
question
r 機械学習
R言語の外積演算関数 outer() を利用して、任意の自作関数（ガウス核関数 GaussianKernel() ）の z軸の値を求める際の関数の挙動について
`outer()`関数の挙動というより，自作関数`GaussianKernel()`内でのデータの扱いでエラー(dimが異なる行列で減算を指示，など)があるように思います。関数内のコードを参考に，以下のような関数を組んでみました:

```

    GaussianKernel2 <- function( x1, x2, alpha, mean, matSigma )
    {
      datX <- cbind(x1,x2) #cbindで列をキープ
      mean <- matrix(rep(mean, each = nrow(datX)), ncol = ncol(datX)) #datXと同次元の行列へ
      devX <- t(datX - mean) #先に差を計算。ただし以降の計算で使えるよう転置。
      #print(datX)
      #print(mean)
      gauss <- ( solve( matSigma ) %*% devX )
      #print(gauss)  
      gauss <- ( -alpha*t( devX )%*%gauss ) 
      gauss <- exp( gauss )
    
      return( gauss )
    }
    
```

そして`outer()`を適用せず，この関数だけで，求めたいzの値は得られるのではないかと思います:

```

    lstGKernel <- list(
      x1 = seq( from=0, to=10, by=0.1 ),
      x2 = seq( from=0, to=10, by=0.1 ),
      z = matrix( 0, nrow = 100, ncol = 100 ),
    
      dat_alpha = 0.005,
      vec_u = c( -7.61,0.22 ),
      matS = matrix( c(0.72,-0.53,-0.53,0.84), nrow = 2, ncol = 2 )
    )
    
    lstGKernel$z <- GaussianKernel2( 
      lstGKernel$x1, lstGKernel$x2, 
      lstGKernel$dat_alpha, lstGKernel$vec_u ,lstGKernel$matS
    )
    
```

この計算結果から`scatterplot3d()`で作図する方法については，同関数のヘルプにあるexample4が参考になるかと思い，それをベースに作成してみました:

```

    # scatterplot3d用データ作成
    forPlot <- lstGKernel$z
    dimnames(forPlot) <- list(lstGKernel$x1, lstGKernel$x2)
    s3d_dat <- data.frame(
      x1=as.vector(col(forPlot)),
      x2=as.vector(row(forPlot)),
      value=as.vector(forPlot)
    )
    # 作図
    scatterplot3d(s3d_dat, type = "h", pch = " ",
                  x.ticklabs = colnames(forPlot), y.ticklabs = rownames(forPlot),
                  highlight.3d = TRUE)
    
```

手元では図が表示されるようになりましたが，数学的な処理において間違いがありましたらご指摘いただけると助かります。
CC BY-SA 3.0
2017-02-07T05:33:11.020
32452
2017-02-07T05:33:11.020
19063
32385
answer