简体   繁体   English

用Linq计算余弦和正弦

[英]Compute cosine and sine with Linq

I maded some code to compute the sine and cosine, but, the code is not so good, I want to know if is possible to make the code to compute the values with Linq. 我编写了一些代码来计算正弦和余弦,但是,该代码并不是很好,我想知道是否可以使该代码使用Linq计算值。

that is my code to compute sine 那是我计算正弦的代码

        var primes = PrimeNumbers(3, 15);

        bool SumSub = false;
        decimal seno = (decimal)(nGrau * nSeno);
        foreach (var a in primes)
        {
            if (SumSub == false)
            {
                seno -= (decimal)Math.Pow(nGrau, (double)a) / Factorial(a);
                SumSub = true;
            }
            else
            {
                seno += (decimal)Math.Pow(nGrau, (double)a) / Factorial(a);
                SumSub = false;
            }
        }
        Console.WriteLine(seno);

Is possible to make a code to compute the sine of degres using linq ? 是否可以使用linq编写代码来计算degres的正弦值?

You could use Aggregate : 您可以使用Aggregate

decimal seno = PrimeNumbers(3, 15)
    .Aggregate(
        new { sub = false, sum = (decimal)(nGrau * nSeno) },
        (x, p) => new {
            sub = !x.sub,
            sum = x.sum + (x.sub ? 1 : -1) * (decimal)Math.Pow(nGrau, (double)p) / Factorial(p)
        },
        x => x.sum);

I didn't test that, but think it should work. 我没有测试过,但认为应该可以。

Btw. 顺便说一句。 I don't think it's more readable or better then your solution. 我认为这比您的解决方案更具可读性或更好。 If I were you I would go with foreach loop, but improve it a little bit: 如果我是你,我会使用foreach循环,但要对其进行一些改进:

foreach (var a in primes)
{
    seno += (SumSub ? 1 : -1) * (decimal)Math.Pow(nGrau, (double)a) / Factorial(a);
    SumSub = !SumSub;
}

Something like this, perhaps: 大概是这样的:

var sineResult = listDouble.Select((item, index) => 
                                    new {i = (index%2)*2 - 1, o = item})
                           .Aggregate(seno, (result, b) => 
                                      result - b.i * ((decimal)Math.Pow(nGrau, (double)b.o) / Factorial(b.o)));

The code 编码

i = (index%2)*2 - 1

gives you alternating 1 and -1. 给您交替的1和-1。

The Aggregate statement sums the values, mulitplying each value by either -1 or 1. Aggregate语句对值求和,将每个值乘以-1或1。

Here's a function that computes the adds up the first 10 terms of the Taylor series approximation of cosine: 这是一个函数,计算余弦的泰勒级数逼近的前10个项的和:

var theta = 1.0m;   // angle in radians
Enumerable.Range(1, 10).Aggregate(
    new { term = 1.0m, accum = 0.0m },
    (state, n) => new {
             term  = -state.term * theta * theta / (2 * n - 1) / (2 * n),
             accum = state.accum + state.term},
    state => state.accum)

See how it doesn't use an if , Power , or Factorial ? 看看它如何不使用ifPowerFactorial The alternating signs are created simply by multiplying the last term by -1 . 只需将最后一项乘以-1即可创建交替符号。 Computing the ever-larger exponents and factorials on each term is not only expensive and results in loss of precision, it is also unnecessary. 在每个术语上计算越来越大的指数和阶乘不仅昂贵而且会导致精度损失,这也是不必要的。

To get x^2 , x^4 , x^6 ,... all you have to do is multiply each successive term by x^2 . 要获得x^2x^4x^6 …,您要做的就是将每个连续项乘以x^2 To get 1/1! 得到1/1! , 1/3! 1/3! , 1/5! ,1/ 1/5! ,... all you have to do is divide each successive term by the next two numbers in the series. ,...您要做的就是将每个连续项除以序列中的下两个数字。 Start with 1 ; 1开始; to get 1/3! 得到1/3! , divide by 2 and then 3; ,除以2再乘以3; to get 1/5! 得到1/5! divide by 4 and then 5, and so on. 除以4再乘以5,依此类推。

Note that I used the m prefix to denote decimal values because I'm assuming that you're trying to do your calculations in decimal for some reason (otherwise you would use Math.Cos ). 请注意,我使用m前缀表示decimal值,因为我假设您出于某种原因试图使用decimal进行计算(否则,您将使用Math.Cos )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM