-1

Looking for a simple way to get the variance of an array of numbers, that will compile with the Arduino compiler. Something like this c#:

static float variance(double []a, int n)
{
    // Compute mean (average of elements)
    double sum = 0;

    for (int i = 0; i < n; i++) sum += a[i];
    double mean = (double)sum / (double)n;
    // Compute sum squared differences with mean.
    double sqDiff = 0;
    for (int i = 0; i < n; i++)
        sqDiff += (a[i] - mean) * (a[i] - mean);
    return (float)sqDiff / n;
}


// Driver Code
public static void Main ()
{
    double []arr = {10, 11, 12, 13};
    int n = arr.Length;
    Console.WriteLine( "Variance: " + variance(arr, n));
}

To keep it simple, and thanks for all your help.... it is a platform with actuators in each corner to raise and lower the platform.... Each actuator sends a feed back via modbus to the main micro processor at its request Which is stored to a array, which is processed and then sent via modbus Back to control (simple on/off) each actuator to keep platform in somewhat of a level position +/- a set number.... I already use the min/max (max – min = ) in the my code to limit a set, simple differential between the Actuators.... I am thinking that using the variance differential would work better for the application.... Thinking it would also detect a jammed or faulty actuator faster than the max/min difference with Less platform twisting.... (Response to Edgar), You could look at it as XYZ,… X= position.. Y= actuator.. Z=sample rate

This is my code snip it for the max/min

example 1 — adj_str = actuators position = (10,11,10,9) run level flag 1

example 2 — adj_str = actuators position = (10,14,10,9) run level flag 0

void min_max()
{
    int max = adj_str[0];
    int min = adj_str[0];
    for (int i = 0; i <= 3; i++)
    {
        const int value = adj_str[i];
        if (value > max) max = value ;
        if (value < min) min = value ;
    }
    //-
    adj_str_dif = max - min;
    //-
    if (adj_str_dif < 1) level_flag = 1;
    //-
    if ((level_flag == 1)&&(adj_str_dif > 4))  // 4 = the differential
    { level_flag = 0;}
    //-
    if (level_flag == 0)           // Level Till Max or Min (re-level)
    {
        // -- Lower --
        if (adj_str_dif > 0 && (digitalRead(but_pin[1]) == LOW))
            base = (max);
        // -- Raise --
        if (adj_str_dif > 0 && (digitalRead(but_pin[2]) == LOW))
            base = (min);
    }
    //-
    if (level_flag == 1)       // Run Till full retract or full extend
    {
        // -- Lower --
        if (adj_str_dif < 1 && (digitalRead(but_pin[1]) == LOW))
            base = 1023;
        // -- Raise --
        if (adj_str_dif < 1 && (digitalRead(but_pin[2]) == LOW))
            base = 0;
    }
}
10
  • 3
    general programming question ... not an arduino related question ... off topic here ... please post at stackoverflow.com/questions instead
    – jsotola
    Nov 30 '20 at 23:17
  • Your example code takes an array of doubles; do you really want to take your input from a string? From a single string containing all of the data? Perhaps comma separated? Perhaps with white-space permitted but ignored (only between values, not within any), .... So your question, not only not Arduino-specific, is also not sufficiently specified to be able to answer it. Assuming I guessed right, you'd need to read the string, collect each value, convert it to double, and stash it in an array to be passed as 'a' to your function 'variance()'.
    – JRobert
    Dec 1 '20 at 0:14
  • the example code is from geeksforgeeks.org/…
    – Eric V
    Dec 1 '20 at 2:45
  • JRoberts..... the example code is from [link] geeksforgeeks.org/…) ..... i was hoping to change this a bit to run some tests on the Arduino IDE.... i already have a string setup that contains multiple ADC readings, and if i am correct in my assumption i can use the variance result to flag an execution.. i do like the bell curve it creates and thinking it may work for my project
    – Eric V
    Dec 1 '20 at 3:05
  • 1
    This looks very much like an XY Problem. You seem to be asking the wrong question, for several reasons: 1. If your data comes from the Arduino's ADC, converting the numbers to a string, only to convert them back to numbers, is both useless and incredibly wasteful. 2. This algorithm for the variance requires you to read the array twice. Not the method you want to use on a microcontroller. You want to do it in a single pass, as you read the ADC, so you do not have to ever store the measurements. Please, tell us what you actually want to achieve. Dec 1 '20 at 8:29
1

C++ and C# (or Java) basic language constructs are very similar. Here is the Arduino version of your C# code with minimal required modifications. There is no change in the function implementation.


float variance(double a[], int n) 
{   
    // Compute mean (average of elements) 
    double sum = 0; 
    
    for (int i = 0; i < n; i++) sum += a[i];    
    double mean = (double)sum / (double)n; 
    // Compute sum squared differences with mean. 
    double sqDiff = 0; 
    for (int i = 0; i < n; i++) 
        sqDiff += (a[i] - mean) * (a[i] - mean); 
    return (float)sqDiff / n; 
} 


void setup() {
    Serial.begin(115200);
    double arr[] = {10, 11, 12, 13}; 
    int n = sizeof(arr) / sizeof(double); 
    Serial.print( "Variance: ");
    Serial.println(variance(arr, n));                            
}

void loop() {

}
2
  • Thanks ... will try running this later tonite
    – Eric V
    Dec 1 '20 at 17:51
  • Works as posted
    – Eric V
    Dec 4 '20 at 4:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.