Loop incrementing operations for sugarcane replication - c#

I'm creating an algorithm to calculate area for sugarcane replication.
I have an initial planted area of 5 hectares. These 5 hectares will be cut off when fully grown and then cloned in the proportion of 1:7 So my second area will have 35 Hectares (5*7)
The next areas will have a decreased propotion, because it gets lower at every cut.
So the third area will be (5*6) + (35*7)
forth area: (5*5) + (35*6) + (245 * 7) and so on. The user will input number for iteration and proportions to multiply.
doing by hand it would something like this:
area[0] = initialArea;
area[1] = area[0] * proportion[0]; // = 35
area[2] = area[0] * proportion[1] + area[1] * proportion[0];
area[3] = (area[0] * proportion[2]) + (area[1] * proportion[1]) + (area[2] * proportion[0]);
area[4] = (area[0] * proportion[3]) + (area[1] * proportion[2]) + (area[2] * proportion[1]) + (area[3] * proportion[0]);
area[5] = (area[0] * proportion[4]) + (area[1] * proportion[3]) + (area[2] * proportion[2]) + (area[3] * proportion[1]) + (area[4] * proportion[0]);
Is there a way I can put this inside a loop?

Yes, you can make that into a for-loop.
The loop for each iteration is:
for (int n = 0; n < iteration; n++)
{
area[iteration] += area[n] * proportion[iteration - n - 1];
}
which you can wrap with the number of iterations:
for (int i = 1; i <= iterations; i++)
{
for (int n = 0; n < i; n++)
{
area[i] += area[n] * proportion[i - n - 1];
}
}
you will have to intialize with area[0] = intialArea. With input:
Console.Write("Enter inital area: ");
double initialArea = double.Parse(Console.ReadLine());
Console.Write("Enter proportions, separate each proportion with spaces: ");
string input = Console.ReadLine();
double[] proportion = input.Split(' ').Select(x => double.Parse(x)).ToArray();
int iterations = proportion.Length;
Console.WriteLine($"Using {iterations} iterations");
double[] area = new double[proportion.Length + 1];
area[0] = initialArea;
for (int i = 1; i <= iterations; i++)
{
Console.Write($"Iteration = {i}: ");
for (int n = 0; n < i; n++)
{
area[i] += area[n] * proportion[i - n - 1];
Console.Write($"area[{n}] = {area[n]} ");
}
Console.WriteLine();
}
Console.ReadLine();

Related

Print all points in an infinite grid of n dimensions

I can not have infinite points stored in the computer, but what I mean by that is the max value of Int64 (long).
I could use a nested loop, but that would take an eternity to go to the next line, so I found another way.
All the points whose x and y values add upto n are on a diagonal.
(0,0) - 0
(1,0),(0,1) - 1
(2,0),(1,1),(0,2) - 2
(all of these are diagonals)
So we could iterate through all values of n, from 0 to max value of long, that would give us all the points on all the diagonals.
So I wrote the code to do this.
public void Main()
{
for(long i = 0; i < Int64.MaxValue; i++)
{
long[] a = new long[(i + 1)];
long[] b = new long[(i + 1)];
for(long j = 0; j <= i; j++)
{
a[j] = j;
b[j] = (i - a[j]);
}
f(a,b);
}
}
public void f(long[] a, long[] b)
{
string toPrint = "";
for(int i = 0; i < a.Length; i++)
{
toPrint += "(" + a[i] + "," + b[i] + "),";
}
Console.Write(toPrint + "\n\n");
}
It does the job for a grid of 2 dimensions, but I want it to work for n dimensions, the same idea applies

Finding employee that made the most from array?

I have managed to get the "least" Calculated however the code for "most" is not working... what I have currently.
for (int i = 0; i < workerGrossIncome.Length; i++)
if (workerGrossIncome[i] > workerGrossIncome[maxIndex])
{
maxIndex = i;
workerMost = workerName[i];
workerRegularPayMost = workersRegularPay[i];
workerGrossIncomeMost = workerGrossIncome[i];
}
edit with full code: (Currently Learning cannot use built in array methods)
Program runs however uses the defaults when calculating for the worker that made the most during the work week.
const double FEDERAL_TAX_DEDUCTION = .10; //10% of Gross Income
const double STATE_TAX_DEDUCTION = .05; //5% of Gross Income
const double workerOvertimePay = 0.00; //If Employee Does No Overtime
static void Main(string[] args)
{
int MAX_LIST_VALUE;
Write("How Many Worker's Are Working? ");
MAX_LIST_VALUE = Convert.ToInt32(ReadLine());
string[] workerName = new string[MAX_LIST_VALUE];
for (int i = 0; i < MAX_LIST_VALUE; i++)
{
WriteLine("Please Enter The Worker's Name: ");
workerName[i] = ReadLine();
}
double[] workerWages = new double[MAX_LIST_VALUE];
for (int i = 0; i < MAX_LIST_VALUE; i++)
{
WriteLine("Please Enter The Worker's Hourly Wage: ");
workerWages[i] = Convert.ToDouble(ReadLine());
}
double[] workerWeeklyHours = new double[MAX_LIST_VALUE];
for (int i = 0; i < MAX_LIST_VALUE; i++)
{
Write("How many hours has {0} worked this week? ", workerName[i]);
workerWeeklyHours[i] = Convert.ToDouble(ReadLine());
}
double[] workersRegularPay = new double[MAX_LIST_VALUE];
double[] workerGrossIncome = new double[MAX_LIST_VALUE];
double[] workerStateTaxAmount = new double[MAX_LIST_VALUE];
double[] workerFederalTaxAmount = new double[MAX_LIST_VALUE];
double[] workerNetIncome = new double[MAX_LIST_VALUE];
for (int i = 0; i < MAX_LIST_VALUE; i++)
{
workersRegularPay[i] = workerWeeklyHours[i] * workerWages[i];
workerGrossIncome[i] = workerWeeklyHours[i] * workerWages[i];
workerStateTaxAmount[i] = workerGrossIncome[i] * STATE_TAX_DEDUCTION;
workerFederalTaxAmount[i] = workerGrossIncome[i] * FEDERAL_TAX_DEDUCTION;
workerNetIncome[i] = workerGrossIncome[i] - workerFederalTaxAmount[i] - workerStateTaxAmount[i];
}
WriteLine("There Are " + MAX_LIST_VALUE + " Workers!");
for (int i = 0; i < MAX_LIST_VALUE; i++)
{
WriteLine("Worker's Name: " + workerName[i]);
WriteLine(workerName[i] + " Hourly Wage: " + workerWages[i].ToString("C"));
WriteLine(workerName[i] + " Hours Wokred This Week: " + workerWeeklyHours[i]);
WriteLine(workerName[i] + " Regular Pay: " + workersRegularPay[i].ToString("C"));
WriteLine(workerName[i] + " Gross Income Pay: " + workerGrossIncome[i].ToString("C"));
WriteLine(workerName[i] + " State Tax Amount: " + workerStateTaxAmount[i].ToString("C"));
WriteLine(workerName[i] + " Federal Tax Amount: " + workerFederalTaxAmount[i].ToString("C"));
WriteLine(workerName[i] + " Net Income: " + workerNetIncome[i].ToString("C"));
}
ForegroundColor = ConsoleColor.Red;
WriteLine("\nPress Enter To Continue For Worker's That Earned The Least & Most.");
ReadLine();
int minIndex = 0;
string workerLeast = "null";
double workerRegularPayLeast = 0,
workerGrossIncomeLeast = 0,
workerOverTimeLeast = 0;
int maxIndex = 0;
string workerMost = "null";
double workerRegularPayMost = 0,
workerGrossIncomeMost = 0,
workerOverTimeMost = 0;
for (int i = 0; i < workerGrossIncome.Length; i++)
if (workerGrossIncome[i] < workerGrossIncome[minIndex])
{
minIndex = i;
workerLeast = workerName[i];
workerRegularPayLeast = workersRegularPay[i];
workerGrossIncomeLeast = workerGrossIncome[i];
}
for (int i = 0; i < workerGrossIncome.Length; i++)
if (workerGrossIncome[i] > workerGrossIncome[maxIndex]) //Doesnt calc the most..... FIX
{
maxIndex = i;
workerMost = workerName[i];
workerRegularPayMost = workersRegularPay[i];
workerGrossIncomeMost = workerGrossIncome[i];
}
ForegroundColor = ConsoleColor.Green;
WriteLine("\nThe Worker That Earned The Least Is {0}!", workerLeast);
WriteLine("{0}'s Gross Income Was {1}.", workerLeast, workerGrossIncomeLeast.ToString("C"));
WriteLine("{0}'s Regular Pay Was {1}.", workerLeast, workerRegularPayLeast.ToString("C"));
WriteLine("{0}'s Overtime Pay Was {1}.", workerLeast, workerOverTimeLeast.ToString("C"));
ForegroundColor = ConsoleColor.Cyan;
WriteLine("\nThe Worker That Earned The Most Is {0}!", workerMost);
WriteLine("{0}'s Gross Income Was {1}.", workerMost, workerGrossIncomeMost.ToString("C"));
WriteLine("{0}'s Regular Pay Was {1}.", workerMost, workerRegularPayMost.ToString("C"));
WriteLine("{0}'s Overtime Pay Was {1}.", workerMost, workerOverTimeMost.ToString("C"));
ReadLine();
}
}
Error is in the loop for worker earning the most. The rest is fine for whats needed.
Without LINQ
If you can't use LINQ, then change your maxIndex variable declaration to:
int? maxIndex = null;
And the start of your loop to:
for (int i = 0; i < workerGrossIncome.Length; i++)
if (maxIndex == null || workerGrossIncome[i] > workerGrossIncome[maxIndex.Value])
to ensure that the code work even when the first element is the largest one.
Your existing code does not work if the first element is the largest since workerGrossIncome[i] > workerGrossIncome[maxIndex] will be false and thus workerMost etc won't be set.
With LINQ
If you add the MoreLINQ Nuget Package then maxIndex can be calculated as follows:
// Sample Data
int[] workerGrossIncome = new[] {1, 2, 4};
var maxIndex = workerGrossIncome
.Select((value, index) => new {index, value})
.MaxBy(z => z.value)
.index;
var workerMost = workerName[i];
var workerRegularPayMost = workersRegularPay[i];
var workerGrossIncomeMost = workerGrossIncome[i];
Select will project the original data and the index. MaxBy will find the item with the largest value. index will return the index of that matching item.

Converting a one minute tick data to a five minute OHLC without pandas C#

I am getting once minute data (OHLC) from a data feed (lmax) and I want to re-sample this to a five minute data and ten, fifteen and thirty later on.
I'm using the following logic:
Open=first value of every 5 candles (1st candle open)
High=Highest value of 5 candle
Low=Lowest value of 5 candles
Close=Close of the last candle (5th candle)
Is this the correct way to re-sample data? I feel that this is logical but for some reason there are visible differences between the data feed on their site and my code. I feel that this is the case because I re-sampled it wrong; if i was using Python, I could refer to pandas but not in C# (to my knowledge).
This is the function which resamples the data:
private static List<List<double>> normalize_candles(List<List<double>> indexed_data, int n)
{
double open = 0;
double high = 0;
double low = 5;
double close = 0;
int trunc = 0;
if (indexed_data.Count() % n != 0)
{
trunc = indexed_data.Count() % n;
for (int i = 0; i < trunc; i++)
{
indexed_data.RemoveAt(indexed_data.Count() - 1);
}
}
{
}
List<List<double>> normal_candle_data = new List<List<double>>();
for (int i = 0; i < indexed_data.Count() / n; i++)
{
high = 0;
low = 100;
open = indexed_data[i * n][0];
close = indexed_data[(i * n) + (n - 1)][3];
for (int j = 0; j < n; j++)
{
if (high < indexed_data[(i * n) + j][1])
{
high = indexed_data[(i * n) + j][1];
}
if (low > indexed_data[(i * n) + j][2])
{
low = indexed_data[(i * n) + j][2];
}
}
normal_candle_data.Add(new List<double>());
normal_candle_data[i].Add(open);
normal_candle_data[i].Add(high);
normal_candle_data[i].Add(low);
normal_candle_data[i].Add(close);
}
Console.WriteLine("\n\n");
foreach (var obj in normal_candle_data)
{
Console.WriteLine(obj[0] + "," + obj[1] + "," + obj[2] + "," + obj[3]);
}
Console.WriteLine("size of orignal data is : " + indexed_data.Count() + "\nSize of normalized data is : " + normal_candle_data.Count());
return normal_candle_data;
}

Simple DFT Lowpass

I'm having some trouble making a simple lowpass filter with a DFT. In the end, I hope to be able to pitch-shift audio in real time, but as it stands I can't even get this right. I have no training in this area, I only know that FFTs change waves to frequencies and iFFTs do that back, and a couple of other things I've read. To bo honest I'm surprised it works as well as it does so far. Anyway here's the code:
byte[] samples = new byte[20000000];
int spos = 0;
samples is filled here with 8Bit Unsigned PCM. spos <- number of samples
int samplesize = 128;
int sampleCount = spos / samplesize;
frequencies = new System.Numerics.Complex[sampleCount][];
for (int i = 0; i < sampleCount; i++)
{
Console.WriteLine("Sample " + i + " / " + sampleCount);
frequencies[i] = new System.Numerics.Complex[samplesize];
for (int j = 0; j < samplesize; j++)
{
frequencies[i][j] = (float)(samples[i * samplesize + j] - 128) / 128.0f;
}
dft.Radix2Forward(frequencies[i], MathNet.Numerics.IntegralTransforms.FourierOptions.Default);
}
int shiftUp = 1000; //1khz
int fade = 2; //8 sample fade.
int kick = frequencies[0].Length * shiftUp / rate;
So now I've calculated a bunch of DFTs for 128 sample portions of the input. kick is (I hope) the number of samples in the DFT that span 1000Hz. I.E since frequencies.Length / 2 contains frequency amplitude data up to rate/2 Hz, then frequencies[0].Length / 2 * shiftUp / (rate / 2) = frequencies[0].Length * shiftUp / rate should give me the right value
for (int i = 0; i < sampleCount; i++)
{
This is the part I have trouble with. Without it, the output sounds great! This skips both index 0 and index 64. Both of these have a complex component of 0, and I recall reading somewhere that the value at index 0 was important...
for (int j = 0; j < frequencies[i].Length; j++)
{
if (j == 0 || j == 64)
continue;
if (j < 64)
{
if (!(j < kick + 1))
{
frequencies[i][j] = 0;
}
}
else
{
if (!(j - 64 > 63 - kick))
{
frequencies[i][j] = 0;
}
}
}
Finally it undoes the transform
dft.Radix2Inverse(frequencies[i], MathNet.Numerics.IntegralTransforms.FourierOptions.Default);
...tosses it back in the samples array
for (int j=0; j<samplesize; j++)
samples[i * samplesize + j] = (byte)(frequencies[i][j].Real * 128.0f + 128.0f);
}
...chucks it into a file
BinaryWriter bw = new BinaryWriter(File.OpenWrite("sound"));
for (int i = 0; i < spos; i++)
{
bw.Write(samples[i]);
}
bw.Close();
...then I import it into Audacity to murder my ears with artifacts.
The spectral display shows that the code works, to an extent
However there's these annoying highpitched crackling sounds that occur throughout the entire song. I've heard something about the Gibbs phenomenon and a window function, but I don't really know how to apply that here. The fade variable is my best attempt at a window function: everything past the 1000hz mark fades to 0 in 2 samples.
Any ideas?
Thanks!
So it turns out that I was right (yay): Every 1024 samples I was getting a click sound which made the audio sound awful. To fix this, I faded inbetween many short overlapping chunks of filtered audio. It's not fast, but it works, and I'm pretty sure this is what they mean by "windowing"
public class OggDFT
{
int sample_length;
byte[] samples;
DragonOgg.MediaPlayer.OggFile f;
int rate = 0;
System.Numerics.Complex[][] frequencies;
DiscreteFourierTransform dft = new DiscreteFourierTransform();
int samplespacing = 128;
int samplesize = 1024;
int sampleCount;
public void ExampleLowpass()
{
int shiftUp = 1000; //1khz
int fade = 2; //8 sample fade.
int halfsize = samplesize / 2;
int kick = frequencies[0].Length * shiftUp / rate;
for (int i = 0; i < sampleCount; i++)
{
for (int j = 0; j < frequencies[i].Length; j++)
{
if (j == 0 || j == halfsize)
continue;
if (j < halfsize)
{
if (!(j < kick + 1))
{
frequencies[i][j] = 0;
}
}
else
{
if (!(j - halfsize > halfsize - 1 - kick))
{
frequencies[i][j] = 0;
}
}
}
dft.BluesteinInverse(frequencies[i], MathNet.Numerics.IntegralTransforms.FourierOptions.Default);
}
}
public OggDFT(DragonOgg.MediaPlayer.OggFile f)
{
Complex[] c = new Complex[10];
for (int i = 0; i < 10; i++)
c[i] = i;
ShiftComplex(-2, c, 5, 10);
this.f = f;
//Make a 20MB buffer.
samples = new byte[20000000];
int sample_length = 0;
//This block here simply loads the uncompressed data from the ogg file into a nice n' large 20MB buffer. If you want to use the same library as I've used, It's called DragonOgg (If you cant tell by the namespace)
while (sample_length < samples.Length)
{
var bs = f.GetBufferSegment(4096); //Get ~4096 bytes (does not gurantee that 4096 bytes will be returned.
if (bs.ReturnValue == 0)
break; //End of file
//Set the rate
rate = bs.RateHz;
//Display some loading info:
Console.WriteLine("seconds: " + sample_length / rate);
//It's stereo so we want half the data.
int max = bs.ReturnValue / 2;
//Buffer overflow care.
if (samples.Length - sample_length < max)
max = samples.Length - sample_length;
//The copier.
for (int j = 0; j < max; j++)
{
//I'm using j * 2 here because I know that the input audio is 8Bit Stereo, and we want just one mono channel. So we skip every second one.
samples[sample_length + j] = bs.Buffer[j * 2];
}
sample_length += max;
if (max == 0)
break;
}
sampleCount = (sample_length - 1) / samplespacing + 1;
frequencies = new System.Numerics.Complex[sampleCount][];
for (int i = 0; i < sample_length; i += samplespacing)
{
Console.WriteLine("Sample---" + i + " / " + sample_length);
System.Numerics.Complex[] sample;
if (i + samplesize > sample_length)
sample = new System.Numerics.Complex[sample_length - i];
else
sample = new System.Numerics.Complex[samplesize];
for (int j = 0; j < sample.Length; j++)
{
sample[j] = (float)(samples[i + j] - 128) / 128.0f;
}
dft.BluesteinForward(sample, MathNet.Numerics.IntegralTransforms.FourierOptions.Default);
frequencies[i / samplespacing] = sample;
}
//Perform the filters to the frequencies
ExampleLowpass();
//Make window kernel thingy
float[] kernel = new float[samplesize / samplespacing * 2];
for (int i=0; i<kernel.Length; i++)
{
kernel[i] = (float)((1-Math.Cos(2*Math.PI*i/(kernel.Length - 1)))/2);
}
//Apply window kernel thingy
for (int i = 0; i < sample_length; i++)
{
int jstart = i / samplespacing - samplesize / samplespacing + 1;
int jend = i / samplespacing;
if (jstart < 0) jstart = 0;
float ktotal = 0;
float stotal = 0;
for (int j = jstart; j <= jend; j++)
{
float kernelHere = 1.0f;
if (jstart != jend)
kernelHere = kernel[(j - jstart) * kernel.Length / (jend + 1 - jstart)];
int index = i - j * samplespacing;
stotal += (float)frequencies[j][index].Real * kernelHere;
ktotal += kernelHere;
}
if (ktotal != 0)
{
stotal /= ktotal;
samples[i] = (byte)(stotal * 128 * 0.9f + 128);
}
else
{
Console.WriteLine("BAD " + jstart + " " + jend + " sec: " + ((float)i / rate));
samples[i] = (byte)(stotal * 128 * 0.9f + 128);
}
}
BinaryWriter bw = new BinaryWriter(File.OpenWrite("sound"));
for (int i = 0; i < sample_length; i++)
{
bw.Write(samples[i]);
}
bw.Close();
}
}
If you want to compile this, you'll need DragonOgg (http://sourceforge.net/projects/dragonogg/) and MathNet.Numerics (http://mathnetnumerics.codeplex.com/)
I hope it helps someone - I don't know about how StackOverflow licences by default, but this code as it stands is public domain.
On further thought, I decided I could achieve an approximated effect much easier by simply "blurring" the samples to get a basic low pass filter. A high pass filter can be made by subtracting the result of the low pass.

Circular moving average filter in LINQ

I'm looking for an elegant way to implement a moving average filter in c#. Now, that would be easy, but at the borders, the averaging window shall wrap around the start/end. This kind of made my code ugly and unintuitive, and I was wondering whether there was a smarter way to solve this using LINQ or so.
So what I currently have is:
// input is a List<double> y, output is List<double> yfiltered
int yLength = y.Count;
for (int i = 0; i < yLength; i++)
{
double sum = 0.0;
for (int k = i - halfWindowWidth; k <= i + halfWindowWidth; k++)
{
if (k < 0)
{
// k is negative, wrap around
sum += y[yLength - 1 + k];
}
else if (k >= yLength)
{
// k exceeds y length, wrap around
sum += y[k - yLength];
}
else
{
// k within y.Count
sum += y[k];
}
}
yfiltered[i] = sum / (2 * halfWindowWidth + 1);
}
Here is a completely other suggestion -
I was trying to actually make it better, rather than more readable.
The problem with your current code is that it sums up many numbers again and again, when not really needed.
Comparing both approaches after the implementation code...
I'm only summing a bunch for the first time, and then subtracting the tail and adding the head, again and again:
double sum = 0;
// sum = Enumerable.Range(i - halfWindowWidth, halfWindowWidth * 2 + 1)
// .Select(k => y[(k + yLength) % yLength]).Sum();
for (var i = -halfWindowWidth; i <= halfWindowWidth; i++)
{
sum += y[(i + yLength) % yLength];
}
yFiltered[0] = sum / (2 * halfWindowWidth + 1);
for (var i = 1; i < yLength; i++)
{
sum = sum -
y[(i - halfWindowWidth - 1 + yLength) % yLength] +
y[(i + halfWindowWidth) % yLength];
yFiltered[i] = sum / (2 * halfWindowWidth + 1);
}
And here are the speed tests, comparing the full-recalculation approach vs. this one:
private static double[] Foo1(IList<double> y, int halfWindowWidth)
{
var yfiltered = new double[y.Count];
var yLength = y.Count;
for (var i = 0; i < yLength; i++)
{
var sum = 0.0;
for (var k = i - halfWindowWidth; k <= i + halfWindowWidth; k++)
{
sum += y[(k + yLength) % yLength];
}
yfiltered[i] = sum / (2 * halfWindowWidth + 1);
}
return yfiltered;
}
private static double[] Foo2(IList<double> y, int halfWindowWidth)
{
var yFiltered = new double[y.Count];
var windowSize = 2 * halfWindowWidth + 1;
double sum = 0;
for (var i = -halfWindowWidth; i <= halfWindowWidth; i++)
{
sum += y[(i + y.Count) % y.Count];
}
yFiltered[0] = sum / windowSize;
for (var i = 1; i < y.Count; i++)
{
sum = sum -
y[(i - halfWindowWidth - 1 + y.Count) % y.Count] +
y[(i + halfWindowWidth) % y.Count];
yFiltered[i] = sum / windowSize;
}
return yFiltered;
}
private static TimeSpan TestFunc(Func<IList<double>, int, double[]> func, IList<double> y, int halfWindowWidth, int iteration
{
var sw = Stopwatch.StartNew();
for (var i = 0; i < iterations; i++)
{
var yFiltered = func(y, halfWindowWidth);
}
sw.Stop();
return sw.Elapsed;
}
private static void RunTests()
{
var y = new List<double>();
var rand = new Random();
for (var i = 0; i < 1000; i++)
{
y.Add(rand.Next());
}
var foo1Res = Foo1(y, 100);
var foo2Res = Foo2(y, 100);
Debug.WriteLine("Results are equal: " + foo1Res.SequenceEqual(foo2Res));
Debug.WriteLine("Foo1: " + TestFunc(Foo1, y, 100, 1000));
Debug.WriteLine("Foo2: " + TestFunc(Foo2, y, 100, 1000));
}
Time complexities:
MyWay: O(n + m)
OtherWay: O(n * m)
Since Foo1 is O(n * m) and Foo2 is O(n + m) it's really not surprising that the difference is huge.
Results on this not really crazy big scale are:
Results are equal: True
Foo1: 5.52 seconds
Foo2: 61.1 milliseconds
And on a bigger scale (replaced 1000 with 10000 on both iterations and count):
Foo1: Stopped after 10 minutes...
Foo2: 6.9 seconds
Expanding on my comment, you could use the mod (%) operator to get k to wrap
from 0 to ylength - 1
// input is a List<double> y, output is List<double> yfiltered
int yLength = y.Count;
for (int i = 0; i < yLength; i++)
{
double sum = 0.0;
for (int k = i - halfWindowWidth; k <= i + halfWindowWidth; k++)
{
sum += y[(k + yLength) % yLength];
}
yfiltered[i] = sum / (2 * halfWindowWidth + 1);
}
for (var i = 0; i < yLength; i++)
{
var sum = Enumerable.Range(i - halfWindowWidth, halfWindowWidth * 2 + 1)
.Select(k => y[(yLength + k) % yLength]).Sum();
yFiltered[i] = sum / (2 * halfWindowWidth + 1);
}
Or even:
var output = input.Select((val, i) =>
Enumerable.Range(i - halfWindowWidth, halfWindowWidth * 2 + 1)
.Select(k => input[(input.Count + k) % input.Count])
.Sum()).ToList();

Categories

Resources