Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用LINQ C计算数组#_C#_Arrays_Linq - Fatal编程技术网

C# 用LINQ C计算数组#

C# 用LINQ C计算数组#,c#,arrays,linq,C#,Arrays,Linq,我想用linq计算相关矩阵,用一个短语。我该怎么做(如果可能的话) 假设我已经有一个称为volatites的大小为N的数组,返回的是一个锯齿状数组,其中N个数组的大小都相同 我还使用: using stats = MathNet.Numerics.Statistics.ArrayStatistics 这是我想在LINQ中编写的代码: double[,] correlation_matrix = new double[N,N]; for (int i=0; i<N;i++){ fo

我想用linq计算相关矩阵,用一个短语。我该怎么做(如果可能的话)

假设我已经有一个称为volatites的大小为N的数组,返回的是一个锯齿状数组,其中N个数组的大小都相同

我还使用:

using stats = MathNet.Numerics.Statistics.ArrayStatistics
这是我想在LINQ中编写的代码:

double[,] correlation_matrix = new double[N,N];
for (int i=0; i<N;i++){
    for (int j = i + 1; j < N; j++){
        correlation_matrix [i,j]= stats.Covariance(Returns[i], Returns[j]) / (volatilities[i] * volatilities[j]); // stores it to check values       
    }
}
double[,]相关矩阵=新的double[N,N];

对于(inti=0;i如果你让自己有一个数组,你可以

var correlation_matrix = 
    Returns.Select((r_i, i) => 
        Returns.Where((r_j, j) => j > i).Select((r_j, j) =>
            stats.Covariance(r_i, r_j) / (volatilities[i] * volatilities[j])
        ).ToArray()
    ).ToArray();
var N = Returns.Length;
var correlation_matrix = 
    Enumerable.Range(0, N).Select(i => 
        Enumerable.Range(i + 1, N - i - 1).Select(j =>
            stats.Covariance(Returns[i], Returns[j]) / (volatilities[i] * volatilities[j])
        ).ToArray()
    ).ToArray();    
如果你想使用范围(根据你的评论),你可以这样做

var correlation_matrix = 
    Returns.Select((r_i, i) => 
        Returns.Where((r_j, j) => j > i).Select((r_j, j) =>
            stats.Covariance(r_i, r_j) / (volatilities[i] * volatilities[j])
        ).ToArray()
    ).ToArray();
var N = Returns.Length;
var correlation_matrix = 
    Enumerable.Range(0, N).Select(i => 
        Enumerable.Range(i + 1, N - i - 1).Select(j =>
            stats.Covariance(Returns[i], Returns[j]) / (volatilities[i] * volatilities[j])
        ).ToArray()
    ).ToArray();    
这并不是说您应该这样做。循环版本更具可读性和性能。

每个OP请求版本都有2d数组,因此:

var correlation_matrix = 
   Enumerable.Range(0, N).Select(i => 
       Enumerable.Range(i + 1, N - i - 1).Select(j => 
         new {
            i, j, // capture location of the result
            Data = i + j } // compute whatever you need here
       )
   )
   .SelectMany(r => r) // flatten into single list
   .Aggregate(
       new double[N,N], 
       (result, item) => { 
           result[item.i, item.j] = item.Data; // use pos captured earlier
           return result; // to match signature required by Aggregate
        });
旁注:这本质上是使用LINQ的练习,而不是应该在实际代码中使用的代码

  • 代码必须捕获匿名对象中的位置,从而导致大量不必要的分配
  • 我认为这个版本要比常规的
    版本更难阅读

我不相信有任何linq操作符可以创建多维数组,因此我不认为您可以将其作为linq单行程序来实现。这种简单的方法(对于循环)有什么问题?linq并不总是您认为的灵丹妙药。如果它有效且可读,那么就别管它:)@Chris您可以使用
Aggregate
来填写2d数组,将代码转换为单个语句,但我怀疑是否有人会将其视为改进。我同意其他人的看法。你目前的方法非常清楚它的作用。我相信你可以写一些很难做到的东西,但是没有比这更清楚的了。我几乎不愿意+1这个,因为正如你所说,原作好得多。但是你说原版更好,所以+1.)谢谢@Jerry!如果一个版本有两个范围,从0到N-1,即{0,1,2,3,…N-1},它会这样做吗?@Escachator注意到,这段代码与您的原始示例相比有一个差异。不确定哪一个是正确的,所以。Alexei是正确的-我已经更正了内部Enumerable.Range的计数。