List vs Array

S

shapper

Hello,

I am translating a few functions from Matlab to C#.
This functions are applied to time series.
A simple example would be a moving average.

Should the time series be:
List<double> series
or
double[]

If i am not wrong a list allows to use Linq and array if better for
indexes.

For example, for a moving average calculation what would you use?

Thank You,
Miguel
 
S

shapper

A good alternative to using an array would be to use the Queue<T> class.  
It uses an array internally, but encapsulates the usual "circular buffer" 
implementation that is often used for moving averages.  

I am not sure if Matlab recongnizes Queue<T>.
I am moving calculation to C# libraries but I need Matlab to still be
able to access them.
The Simple Moving Average is just an example I am using to test C#
code with Time Series, which I will use, and the exchange between
Matlab scripts and C# .NET libraries.

For the SMA I created the following code:

public static Double[] SMA(Double[] series, Int32 period) {

// Check arguments
Int32 length = series.Length;
if (length == 0) throw new ArgumentException("Series cannot be
empty");
if (period < length) throw new ArgumentException("Period cannot
be less than series length");

// Calculate simple moving average
Double[] sma = new Double[length];
Array.Copy(series, sma, period);
for (Int64 bar = period + 1; bar < length; bar++)
sma[bar] = sma[bar - 1] - (series[bar - period + 1] + series
[bar]) / period;
return sma;

} // SMA

I didn't test it yet.

I am having a few problems with importing it into Matlab.
I am going to create a Console Application to test it in VS to.

I am not sure if this is the best code. Any suggestion is welcome.

I am going to use StopWatch as you suggested me before to make my
tests.

Thanks,
Miguel
 
S

shapper

A good alternative to using an array would be to use the Queue<T> class.  
It uses an array internally, but encapsulates the usual "circular buffer" 
implementation that is often used for moving averages.  

I am not sure if Matlab recongnizes Queue<T>.
I am moving calculation to C# libraries but I need Matlab to still be
able to access them.
The Simple Moving Average is just an example I am using to test C#
code with Time Series, which I will use, and the exchange between
Matlab scripts and C# .NET libraries.

For the SMA I created the following code:

public static Double[] SMA(Double[] series, Int32 period) {

// Check arguments
Int32 length = series.Length;
if (length == 0) throw new ArgumentException("Series cannot be
empty");
if (period < length) throw new ArgumentException("Period cannot
be less than series length");

// Calculate simple moving average
Double[] sma = new Double[length];
Array.Copy(series, sma, period);
for (Int64 bar = period + 1; bar < length; bar++)
sma[bar] = sma[bar - 1] - (series[bar - period + 1] + series
[bar]) / period;
return sma;

} // SMA

I didn't test it yet.

I am having a few problems with importing it into Matlab.
I am going to create a Console Application to test it in VS to.

I am not sure if this is the best code. Any suggestion is welcome.

I am going to use StopWatch as you suggested me before to make my
tests.

Thanks,
Miguel
 
S

shapper

I was able to make this work in Matlab using doubles.
I will try with Queue<T> ...

I created a simple Console Application with the SMA with a few fixes
and using StopWatch to check performance.
On my computer it takes around 1 minute to run and the average time
for one test is around 3 miliseconds.

I based my SMA formula on the following:
http://en.wikipedia.org/wiki/Moving_average

And the Console application is as follows:

// Namespaces
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

// ConsoleApp
namespace ConsoleApp {

// Program
class Program {

// Main
static void Main(String[] args) {

Random random = new Random();
Double[] series = new Double[100000];
for (Int32 i = 0; i < 100000; i++) {
series = random.NextDouble() * 10;
}
Stopwatch watch = new Stopwatch();
for (Int32 i = 1; i < 20000; i++) {
if (i == 200) watch.Start();
Double[] sma = SMA(series, 10);
}
watch.Stop();
TimeSpan ts = watch.Elapsed;
String time = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
Console.WriteLine(time);
Console.WriteLine((ts.TotalMilliseconds / (20000 - 200)).ToString
());
Console.WriteLine("Press any key...");
Console.Read();

} // Main

// SMA
public static Double[] SMA(Double[] series, Int32 period) {

// Check arguments
Int32 length = series.Length;
if (length == 0) throw new ArgumentException("Series cannot be
empty");
if (period > length) throw new ArgumentException("Period cannot
be less than series length");

// Calculate simple moving average
Double[] sma = new Double[length];
Array.Copy(series, sma, period);
for (Int32 bar = 0; bar < length; bar++)
if (bar < period)
sma[bar] = series.Take(bar).Sum();
else
sma[bar] = sma[bar - 1] - (series[bar - period + 1] - series
[bar]) / period;
return sma;

} // SMA

} // Program

} // ConsoleApp

I am not sure about, for example, the following:
sma[bar] = series.Take(bar).Sum();

Anyway, any suggestions to improve my code is welcome.

Thank You,
Miguel
 
S

shapper

I was able to make this work in Matlab using doubles.
I will try with Queue<T> ...

I created a simple Console Application with the SMA with a few fixes
and using StopWatch to check performance.
On my computer it takes around 1 minute to run and the average time
for one test is around 3 miliseconds.

I based my SMA formula on the following:
http://en.wikipedia.org/wiki/Moving_average

And the Console application is as follows:

// Namespaces
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

// ConsoleApp
namespace ConsoleApp {

// Program
class Program {

// Main
static void Main(String[] args) {

Random random = new Random();
Double[] series = new Double[100000];
for (Int32 i = 0; i < 100000; i++) {
series = random.NextDouble() * 10;
}
Stopwatch watch = new Stopwatch();
for (Int32 i = 1; i < 20000; i++) {
if (i == 200) watch.Start();
Double[] sma = SMA(series, 10);
}
watch.Stop();
TimeSpan ts = watch.Elapsed;
String time = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
Console.WriteLine(time);
Console.WriteLine((ts.TotalMilliseconds / (20000 - 200)).ToString
());
Console.WriteLine("Press any key...");
Console.Read();

} // Main

// SMA
public static Double[] SMA(Double[] series, Int32 period) {

// Check arguments
Int32 length = series.Length;
if (length == 0) throw new ArgumentException("Series cannot be
empty");
if (period > length) throw new ArgumentException("Period cannot
be less than series length");

// Calculate simple moving average
Double[] sma = new Double[length];
Array.Copy(series, sma, period);
for (Int32 bar = 0; bar < length; bar++)
if (bar < period)
sma[bar] = series.Take(bar).Sum();
else
sma[bar] = sma[bar - 1] - (series[bar - period + 1] - series
[bar]) / period;
return sma;

} // SMA

} // Program

} // ConsoleApp

I am not sure about, for example, the following:
sma[bar] = series.Take(bar).Sum();

Anyway, any suggestions to improve my code is welcome.

Thank You,
Miguel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top