চলমান গড় গণনা করার জন্য দক্ষ অ্যালগরিদম / ডেটা কাঠামো


9

বর্তমানে আমি তাপ পাম্প সিস্টেমে তাপমাত্রা, প্রবাহ, ভোল্টেজ, শক্তি এবং শক্তি প্রদর্শন করার জন্য একটি গ্রাফিক এলসিডি সিস্টেম বিকাশ করছি। একটি গ্রাফিক এলসিডি ব্যবহারের অর্থ আমার এসআরএমের অর্ধেক এবং আমার ফ্ল্যাশের ~ 75% স্ক্রিন বাফার এবং স্ট্রিং ব্যবহার করেছে।

আমি বর্তমানে শক্তির জন্য ন্যূনতম / সর্বাধিক / গড় পরিসংখ্যান প্রদর্শন করছি যখন মধ্যরাতে যখন দৈনিক চিত্রটি পুনরায় সেট করা হয় তখন সিস্টেমটি পরীক্ষা করে যে দিনের জন্য আগের ন্যূনতম বা সর্বাধিকের চেয়ে কম বা মানটি সংরক্ষণ করা হয়। গড় সংখ্যা দিনের সংখ্যার সাথে সংখ্যামূলক শক্তি খরচ ভাগ করে গণনা করা হয়।

আমি গত সপ্তাহ এবং মাসে (সরলতার জন্য 4 সপ্তাহ) অর্থাৎ রোলিং গড়ের দৈনিক গড় প্রদর্শন করতে চাই। বর্তমানে এটিতে গত 28 দিনের মানগুলির একটি অ্যারে বজায় রাখা এবং সাপ্তাহিকের জন্য মাসিক এবং শেষ 7 দিনের জন্য পুরো অ্যারের উপরে গড়ে গণনা করা জড়িত।

প্রাথমিকভাবে আমি এটি একটি ফ্লোটের অ্যারের ব্যবহার করে করছিলাম (শক্তিটি "12.12kWh" আকারে রয়েছে) তবে এটি 28 * 4 বাইট = 112 বাইট (এসআরএম এর 5.4%) ব্যবহার করছিল। আমি কেবলমাত্র এক দশমিক দশমিক পয়েন্ট রেজোলিউশন রাখতে আপত্তি করি না, তাই আমি uint16_t ব্যবহার করে এবং চিত্রটি 100 দ্বারা গুণিত করতে পরিবর্তিত হয়েছি This এর অর্থ হল 12.12 1212 হিসাবে প্রতিনিধিত্ব করা হয়েছে, এবং আমি প্রদর্শনের উদ্দেশ্যে 100 দ্বারা বিভক্ত হয়েছি।

অ্যারের আকার এখন 56 বাইটে নিচে নেমে গেছে (আরও ভাল!)।

আমি দেখতে পাচ্ছি এমন চিত্রটি uint8_t এ কমিয়ে আনার কোনও তুচ্ছ উপায় নেই। দশমিক স্থানের ক্ষতি ("12.12kWh এর পরিবর্তে" 12.1kWh ") সহ্য করতে পারতাম, তবে খরচ প্রায় 25.5kWh এর চেয়ে বেশি (255 সর্বাধিক মান 8-বিট স্বাক্ষরযুক্ত পূর্ণসংখ্যার প্রতিনিধিত্ব করে) is গ্রহণ কখনও 10.0kWh এর নীচে বা 35.0kWh এর উপরে হয় নি, সুতরাং অনুমেয় আমি সংগ্রহিত পরিসংখ্যানগুলি থেকে 10 বিয়োগ করতে পারি, তবে আমি জানি যে একদিন আমরা এই সীমাগুলি অতিক্রম করব।

আমি তখন কোডটি 9-বিট মানগুলিকে একটি অ্যারেতে প্যাক করার জন্য পরীক্ষা করেছিলাম। এটি 0-51.2kWh এর পরিসীমা দেয় এবং মোট 32 বাইট ব্যবহার করে। যাইহোক, এর মতো একটি অ্যারে অ্যাক্সেস করা বেশ ধীর গতির, বিশেষত যখন আপনাকে গড় হিসাবে গণনা করতে সমস্ত মানকে পুনরাবৃত্তি করতে হয়।

সুতরাং আমার প্রশ্নটি হল - তিনটি উইন্ডো - আজীবন, ২৮ দিন এবং days দিন সহ চলন গড় গণনা করার আরও কার্যকর উপায় আছে কি? দক্ষতার অর্থ এসআরএএম ব্যবহারের ক্ষেত্রে ছোট, তবে বিশাল কোডের জরিমানা ছাড়াই। আমি কি সমস্ত মান সংরক্ষণ করা এড়াতে পারি?


আপনি কি নির্দিষ্ট উইন্ডোগুলির উপর থেকে চলমান গড় গণনা করতে চান বা গড়ের একটি প্রাক্কলন / আনুমানিকতা করতে চান?
asheeshr

আমি 7 দিনের এবং 28 দিনের উইন্ডোতে চলমান গড় চাই।
সাইবার্বিবনস

আপনি 0.2kWh এর রেজোলিউশন ব্যবহার করতে পারেন (ফ্যাক্টর 5 দিয়ে বিভক্ত করুন এবং গুণিত করুন) এবং আপনি এখনও 0-51.2kWh পরিসীমা 8 বিটগুলিতে পাবেন
ফ্রিক

আপনি বাইরের র‌্যাম বা বহিরাগত ফ্ল্যাশগুলিতে স্ট্রিং এবং অন্যান্য ধ্রুবক স্থাপন করতে পারেন - দেখুন "আমি যদি ফ্ল্যাশ মেমরি বা এসআরএএম থেকে চলে যাই তবে আমি কী করতে পারি?"
ডেভিড ক্যারি

উত্তর:


2

যদি আপনার ডেটাটিতে নিম্নমানের বিচ্যুতি থাকে, তবে একটি পদ্ধতি হ'ল উইন্ডোটির উপরে মানগুলি যোগ করতে হবে এবং তারপরে নতুন মান যুক্ত করার সময় যোগফল থেকে গড়কে বিয়োগ করতে থাকবে।

কোনও আউটলিয়ার না থাকলে এটি ভালভাবে কাজ করবে , যার ফলে সময়ের সাথে শূন্যের দিকে ঝুঁকির সমষ্টিগত ত্রুটি ঘটবে ।

//Pseudocode

count=0
while new_reading and count<7:
    sum += new_reading        //Calculate the sum of first 7 values
    count++

while new_reading:            //Loop till new readings available
    avg = sum / 7             //Calculate average
    sum -= avg                //Subtract average from sum
    sum += new_reading        //Add next reading to sum
    print avg

2

আপনি একটি ভিন্ন পদ্ধতি ব্যবহার করতে পারেন, আপনি বর্তমান গড় রাখেন এবং তারপরেও করেন

average = (weight1*average+weight2*new_value)/(weight1+weight2);

এটি সত্যিকারের ঘূর্ণায়মান গড়ের নয় এবং এর বিভিন্ন শব্দার্থক শব্দ রয়েছে, তবে এটি আপনার প্রয়োজনগুলি মাপসই করতে পারে

মূল্য সমাধানের জন্য আপনার 9 বিটের জন্য আরও কার্যকর গণনা পদ্ধতির জন্য আপনি মানের 8 টি সর্বোচ্চ বিটকে অ্যারেতে রাখতে পারবেন এবং কমপক্ষে উল্লেখযোগ্য বিটগুলি আলাদা করতে পারবেন:

uint8_t[28] highbits;
uint32_t lowbits;

একটি মান সেট করতে আপনার এটি বিভক্ত করতে হবে

void getvalue(uint8_t index, uint16_t value){
    highbits[index] = value>>1;
    uint32_t flag = (value & 1)<<index;
    highbits|=flag;
    highbits&=~flag;
}

যার ফলে 2 টি একটি শিফট এবং একটি ওআর এবং একটি হয়

গড় গণনা করতে আপনি এটির গতি বাড়ানোর জন্য বিভিন্ন বিট কৌশল ব্যবহার করতে পারেন:

uint16_t getAverage(){
    uint16_t sum=0;
    for(uint8_t i=0;i<28;i++){
        sum+=highbits[i];
    }
    sum<<=1;//multiply by 2 after the loop
    sum+=bitcount(lowbits);
    return sum/28;
}

আপনি একটি ব্যবহার করতে পারেন দক্ষ সমান্তরাল bitcount জন্যbitcount()


1
আপনি কী আরও ব্যাখ্যা করতে পারেন যে কীভাবে এটি আমাকে 7 এবং 28 দিনের গড় গণনা করতে দেয়?
সাইবার্বিবনস

আমি এর আগে শোরগোল অ্যানালগ মানগুলি স্মুথ করার জন্য এই পদ্ধতির ব্যবহার করেছি এবং এটি অবশ্যই যথেষ্ট কার্যকর ছিল। যদিও আমার প্রচুর নির্ভুলতার প্রয়োজন নেই, কারণ ফলাফলগুলি খুব মোটা কোয়ান্টেসিয়ারের মধ্য দিয়ে দেওয়া হচ্ছে। আমারও historicalতিহাসিক গড় প্রয়োজন ছিল না।
পিটার ব্লুমফিল্ড

এটি নির্দিষ্ট উইন্ডোর জন্য গড় গণনা করতে দেয় না।
asheeshr

@ সাইবারিগিবনগুলি আপনি উইন্ডোটি আনুমানিকরূপে বিভিন্ন ওজন ব্যবহার করতে পারেন তাই পুরাতন মানগুলি পূর্বের বা পরে তুচ্ছ হয়ে যায় বা 7 দিনের উইন্ডোর জন্য 7 দিন রাখে এবং এই চলমান গড় 28 দিনের গড়ের জন্য রাখে
র‌্যাচেট ফ্রিক

1

কীভাবে কেবল পূর্বের মান থেকে পার্থক্য সংরক্ষণ করা যায়? ইলেকট্রনিক্সে ডেল্টা সিগমা রূপান্তরকারী নামে একটি অনুরূপ ধারণা রয়েছে যা ডিএ / এডি রূপান্তরকারীদের জন্য ব্যবহৃত হয়। এটি পূর্ববর্তী পরিমাপটি যথাযথভাবে বর্তমানের কাছাকাছি অবস্থার উপর নির্ভর করে।


আরেকটি আকর্ষণীয় ধারণা। দুর্ভাগ্যবশত আমি নিশ্চিত না যে শক্তির খরচ সর্বদা এরূপ হবে, কারণ এটি হিট পাম্প সিস্টেম এবং একদিন 30 কেডব্লুএইচ হতে পারে, পরের 10 কেডব্লুএইচ। আমার সত্যিই ডেটা সংগ্রহ করা এবং দেখার দরকার।
সাইবারবিবোনস

0

কেন আপনি কেবলমাত্র মূল্যগুলি পাওয়ার সাথে সাথে তা যুক্ত করতে পারেন নি। সুতরাং আমি যা বলতে চাইছি তা হল আপনি 1 দিনের মান পান, আপনি এটি 1 দ্বারা ভাগ করে এবং এটি এবং কোথাও 1 টি সঞ্চয় করেন। তারপরে আপনি মানটিকে 1 দিয়ে গুণাবেন এবং এটি পরবর্তী মানের সাথে যুক্ত করুন এবং উভয়কে 2 দ্বারা ভাগ করুন।

এই পদ্ধতিটি করার ফলে আমি ভাবতে পারি এমনভাবে দুটি বা তিনটি ভেরিয়েবলের সাথে রোলিং গড় তৈরি হবে would আমি কিছু কোড লিখব তবে আমি স্ট্যাকেক্সচেঞ্জে নতুন তাই দয়া করে আমাকে সহ্য করুন।


আমি বুঝতে পারছি না যে এটি 7 দিনের এবং 28 দিনের উইন্ডোটির সাথে কী করে?
সাইবারবিবোনস

পূর্ববর্তী এবং পরবর্তী মানগুলি লক্ষ্য রাখুন এবং আপনার চলমান গড় থেকে এগুলি যোগ এবং বিয়োগ করে দিন ...
আদিত্য সোমানী

1
তাহলে আমি ফিরে আসছি 27 দিনের ইতিহাসের স্মরণ করা দরকার, অবশ্যই?
সাইবারবিবোনস

আমি ভাবছিলাম এবং আপনি ঠিক বলেছেন। যাতে প্রযুক্তিগতভাবে আমার উত্তরটি ভুল করে। আমি এতে আরও কিছুটা সময় এবং ধৈর্য বিনিয়োগ করছি। বাক্সের বাইরে কিছু থাকতে পারে। আমি যদি কিছু নিয়ে আসি তবে আপনাকে জানাব। আমরা আমার কর্মক্ষেত্রে এরকম অনেক কিছু করি। আমাকে জিজ্ঞাসা করুন। বিভ্রান্তির জন্য দুঃখিত।
আদিত্য সোমনি

0

... 28 দিন এবং 7 দিন সহ একটি চলন গড় গণনা করার আরও কার্যকর উপায় আছে কি? ... ইতিহাসের 27 দিনের কথা মনে রাখা দরকার ...?

আপনি 28 টি মানের পরিবর্তে 11 টি মান সংরক্ষণের কাছাকাছি পৌঁছে দিতে পারেন, সম্ভবত এর মতো:

// untested code
// static variables
uint16_t daily_energy[7]; // perhaps in units of 0.01 kWh ?
uint16_t weekly_energy[4]; // perhaps in units of 0.1 kWh ?

void print_week_status(){
    Serial.print( F("last week's total energy :") );
    Serial.println( weekly_energy[0] );
    int sum = 0;
    for( int i=0; i<4; i++ ){
        sum += weekly_energy[i];
    };
    Serial.print( F("Total energy over last 4 complete weeks :") );
    Serial.println( sum );
    int average_weekly_energy = sum/4;
    int average_daily_energy = average_weekly_energy/7;
    Serial.print( F("Average daily energy over last 4 weeks :") );
    Serial.println( average_daily_energy );
}
void print_day_status(){
    Serial.print( F("Yesterday's energy :") );
    Serial.println( daily_energy[0] );
    Serial.print( F("average daily energy over the last 7 complete days: ") );
    int sum = 0;
    for( int i=0; i<7; i++ ){
        sum += daily_energy[i];
    };
    int average = sum/7;
    Serial.println( average );
}

অন্য কথায়, গত ২ 27 দিনের জন্য প্রতিদিনের প্রতিটি বিবরণ সংরক্ষণের পরিবর্তে (ক) বিগত or বা এতদিনের জন্য বিশদ দৈনিক তথ্যের মূল্য store বা সেগুলি (খ) স্টোর 4 বা তাই "সংক্ষিপ্ত" গত 4 বা তাই সপ্তাহের প্রত্যেকের জন্য মোট বা গড় তথ্যের মান।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.