I have a variable (double) which has a constantly (infinitely) changing value. I would like to store all the values of this ONE variable into an array. My variable and array are:

Dim x as Double

Private y as Double() = New Double (499) {}

I tried doing this:

y = x

But the error mentions double cannot be converted to one dimensional array of double. May I get some help?

An array is a ordered set of elements of a given length. You can access the each stored element in given array by supplying the index of that position which in turn cannot be larger than the size of the array. So to store a value in the array, you need to supply the array with an index value:

Code:

Dim Length As Integer
Dim MyArray(Length) As Double
' Acess element 6 (since there is a index 0 as well - arrays are zero-based)
MyArray(5) = 5.632626

So as to your problem. If you want to store the current value of your x-variable you need to supply the array with an index in the array. You need a way to keep track of what the index was last time you stored the value of x. Take a look the the following function that adds the current value of x and maintains the value of the next index to be used.

Code:

Private y(499) As Double
Private currentIndex As Integer = 0
Public Sub SaveValue(Byval value As Double)
'save value in array
y(currentIndex) = value
'next time we need to store a value, it must be in the index value 1 higher:
currentIndex += 1
End Sub

__________________
Reading is the foundation for all knowledge - Unknown.

1. Where does my X variable come in then? I don't see it in your example...
2. Also, since it's related, how would I do it the other way round? How would I store all the values in my array back into ONE variable, hence constantly supplying the variable with a new value as time goes by?

Where does my X variable come in then? I don't see it in your example...

In hawkvalley's example, you assign the value to x, the double.
Dim x As Double = 0.01
dbl.Add(x)
In Qua's example, you call the SaveValue function with the value that you want to be in x... e.g. SaveValue(x), where x is still a double.

As far as assigning a value in the array back into one variable, realize that one double variable cannot hold all of its old values, but only one.
You'd have to pick an element... probably something along the lines of:
x = y(0)
This one should get the first value.

As far as assigning a value in the array back into one variable, realize that one double variable cannot hold all of its old values, but only one.
You'd have to pick an element... probably something along the lines of:
x = y(0)
This one should get the first value.

If this is the case then my approach is wrong. Which means I need to ask one more question

I am logging the change in voltage of a small machine and the values of the voltage constantly update my x-variable with a current value which I can show on a graph. The problem is that this data is noisy and I would like to apply a moving average filter. From what I've tried to study, I believe that this means I need to convert the x-variable values into an array (correct me if I'm wrong). I thought that I could convert the variable into an array, filter it, then convert it back into a variable to input into the graph control (Zedgraph). Since this is not possible according to iceplug, what should I be doing instead to filter my data from the x-variable?

I'm not familiar with moving average filters. However, you could use the data stored in the array to calculate general statistics of the values stored. Say you wanted the mean of the stored values you could loop through the array and calculate the mean.

Likewise you could loop through the array and calculate the value needed to plot the next datapoint in your graph.

__________________
Reading is the foundation for all knowledge - Unknown.

I can do that for statistics and I do need to get my statistics too. So what way would you recommend for me to filter the data from my X-variable? If you had to do it, what would your approach be? My graph looks like the one in this page:

Reading the link you supplied (which was interesting reading indead) moving average filter(MAF) is applied on an already known data set. Ie, you supply x elements as input, and as output you recieved y elements that has been filtered with a moving average. Is this how you're doing it as well? Or do you get one point at a time as input? In the latter example I don't see how you'd apply MAF in real time unless you wanted to use n points before you current point to calculate the MAF'ed value of your current point.

__________________
Reading is the foundation for all knowledge - Unknown.

Life is easier when you don't try to write everything in one class.

What you want is to be able to keep the last n data points that came in, and at any time you want to know the average of these n data points. You can easily write a collection class that does this. What if you had a list that, whenever you add an item, if it's over some maximum capacity it will remove the oldest item? Wouldn't this make getting a moving average easy?

This is what the attached project does. MovingAverageList has a MaximumCapacity property that lets you specify the number of samples it keeps. When you call Add, it adds the current value to its list and if the list is too large it removes an item. The GetAverage() method returns the average of the list.

The application generates a random number at a rate of 2 Hz. The random number has a 90% probability of being between 0 and 10 and a 10% probability of being between 0 and 100; this simulates spikes of noise. I set a window of 5 samples. Watch it for a while; you'll know when the spike happens because the average will get significantly larger, but in 5 points it should go back to a lower value.

You can't treat the variable as an array, but you can surely create another variable to represent the previous samples.

__________________ .NET Resources My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.

Thanks Atmaweapon... I completely understand after studying the sample project. I wrote my own modifications to it and it works like a charm. I understand that finally the _averagelist which is basically MovingAverageList which is a class uses the GetAverage() method to churn out the new values. If I wanted to feed these values into another variable, how would I do this?

For example:

Public _averageList As MovingAverageList
Dim X as Double

_averageList.Add(value)
_averageList.GetAverage() ' Which gives me my new value.

But I want to store this as a variable X. How would I do this?

I would implement the MovingAverageList very differently.

It is unnecessary to recalculate the entire sum. When putting a new number in the list, you should subtract the oldest value in the list from the running sum and add the new value to it. Then replace the oldest value with the new one. It is completely unnecessary to keep a list of all the numbers unless you plan on changing the size of the moving average on the fly, which doesn't really make any sense.

Something like:

Code:

Dim Count As Integer ' Size of moving average
Dim Values(Count-1) As Double ' Elements in moving average
Dim Sum As Double ' Accumulating sum
Dim CurrentPosition As Integer ' Keep track of position of last Item added
Dim ItemsAdded As Integer ' Moving average is undefined until we've added "Count" data points
Sub Add(ByVal X As Double)
CurrentPosition = (CurrentPosition+1) Mod Count
X = X / Count
Sum += X - Values(CurrentPosition)
Values(CurrentPosition) = X
ItemsAdded+=1
End Sub
Function GetAverage() As Double
If ItemsAdded >= Count Then
Return Sum
Else
Return 0
End If
End Sub

__________________
To err is human; to debug, divine.

Last edited by darkforcesjedi; 03-19-2009 at 09:47 AM.

I realized I made a mistake with Atmaweapon's code. I need help. The number generator is still providing the data. I already have a variable that's giving me raw data. How do I use that variable as my source instead of atmaweapon's number generator. I tried studying the code but I got confused...

Jedi, that code you provided. Still needs to be called from a module right?

Dim samples(499) As Double
Dim sampleCT As Integer
Dim sampleTOT As Double
Dim sampleIDX As Integer = 0
Private Sub setSampleSize(Optional ByVal NumOfSamples As Integer = 500)
Array.Resize(samples, NumOfSamples)
resetSample()
End Sub
Private Function addNewReading(ByVal reading As Double, _
Optional ByVal FirstReading As Boolean = False) _
As Double
'adds a new reading, and returns a moving average of all samples
If samples.Length = 0 Then Return -1
If FirstReading Then 'if this is the first reading clear the array
resetSample()
End If
sampleTOT += reading
If sampleCT = samples.Length Then 'do we have max samples yet?
'yes
sampleTOT -= samples(sampleIDX) 'subtract oldest
samples(sampleIDX) = reading 'add latest reading
If sampleIDX = samples.Length - 1 Then sampleIDX = 0 Else sampleIDX += 1
Else
'no
samples(sampleCT) = reading 'add latest reading
sampleCT += 1 'increment count of samples taken
End If
'calculate average
Return sampleTOT / sampleCT
End Function
Private Sub resetSample()
Array.Clear(samples, 0, samples.Length)
sampleCT = 0
sampleTOT = 0
sampleIDX = 0
End Sub

I assumed that this needed to be fast which is why I didn't use a List.

Last edited by dbasnett; 03-19-2009 at 11:31 AM.
Reason: make improvements suggested by darkf, again.

I assumed that this needed to be fast which is why I didn't use a List.

Honestly the difference in performance between an array or linked list using this average calculation algorithm is moot. I always added and removed items from the front or back; in a linked list this is O(1). Array access is O(1). Technically, it takes more cycles to do the linked list operation, but I'd be willing to bet that it would take a ridiculously large n to make the performance difference noticeable.

Now the performance difference between recalculating the average each time and the method darkforcesjedi suggested, that's significant. I didn't really bother because it was an example, but good work!

__________________ .NET Resources My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.

List and Array perform about the same as long as you do not remove items from a list. I had this discussion with jmcilhinney at VBForums, and he was surprised. He is the best VB .Net programmer I know.

The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET. subscribe