এই ইন্টিগ্রেশন কোডটি কীভাবে আরও দ্রুত চালানো যায় এটি অনুকূলিত করা সম্ভব?


9
double trap(double func(double), double b, double a, double N) {
  double j;
  double s;
  double h = (b-a)/(N-1.0); //Width of trapezia

  double func1 = func(a);
  double func2;

  for (s=0,j=a;j<b;j+=h){
    func2 = func(j+h);
    s = s + 0.5*(func1+func2)*h;
    func1 = func2;
  }

  return s;
}

ট্র্যাপিজিয়া ব্যবহার করে func()সীমা এর মধ্যবর্তী 1D সংখ্যার একীকরণ (বর্ধিত ট্র্যাপিজিয়াম নিয়ম ব্যবহার করে) এর জন্য উপরের আমার সি ++ কোড ।[a,b]N1

আমি আসলে একটি 3D সংহত করছি, যেখানে এই কোডটি পুনরাবৃত্তভাবে বলা হয়। আমি দিয়ে কাজ করি আমাকে শালীন ফলাফল দেয়।N=50

আরও হ্রাস করা ব্যতীত , কেউ কি উপরে পরামর্শ দিচ্ছেন যে উপরের কোডটিকে কীভাবে দ্রুত চালানো যায়? অথবা, এমনকি, একটি দ্রুত সংহতকরণ পদ্ধতির পরামর্শ দিতে পারে?N


5
এটি প্রশ্নের সাথে সত্যই প্রাসঙ্গিক নয়, তবে আমি আরও ভাল পরিবর্তনশীল নামগুলি বেছে নেওয়ার পরামর্শ দেব suggest ভালো লেগেছে trapezoidal_integrationপরিবর্তে trap, sumবা running_totalপরিবর্তে s(এবং ব্যবহার +=পরিবর্তে s = s +), trapezoid_widthবা dxপরিবর্তে h(বা না, trapezoidal শাসন আপনার পছন্দের স্বরলিপি উপর নির্ভর করে), এবং পরিবর্তন func1এবং func2এটা সত্য যে তারা মূল্যবোধ, না ফাংশন হয় প্রতিফলিত। যেমন func1-> previous_valueএবং func2-> current_value, বা এর মতো কিছু।
ডেভিড জেড

উত্তর:


5

গাণিতিকভাবে, আপনার ভাবটি সমান:

I=h(12f1+f2+f3+...+fn1+12fn)+O((ba)3fn2)

সুতরাং আপনি যে বাস্তবায়ন করতে পারে। যেমনটি বলা হয়েছিল, সময়টি সম্ভবত ফাংশন মূল্যায়নের দ্বারা প্রাধান্য পেয়েছে, সুতরাং একই নির্ভুলতা পেতে আপনি আরও ভাল সংহতকরণ পদ্ধতি ব্যবহার করতে পারেন যার জন্য কম ফাংশন মূল্যায়ন প্রয়োজন।

গাউসিয়ান চতুর্ভুজ আজকের দিনে খেলনা থেকে কিছুটা বেশি; আপনার যদি খুব কম মূল্যায়ন প্রয়োজন হয় কেবল তখনই কার্যকর । আপনি যদি কিছু কার্যকর করতে চান তবে আপনি সিম্পসনের নিয়মটি ব্যবহার করতে পারেন, তবে আমি কোনও ভাল কারণ ছাড়াই অর্ডার than চেয়ে বেশি যেতে চাই না ।1/N3

যদি ফাংশনের বক্রতাটি অনেক পরিবর্তন হয় তবে আপনি একটি অভিযোজনমূলক পদক্ষেপের রুটিন ব্যবহার করতে পারেন, এটি ফাংশন সমতল হওয়ার সময় একটি বৃহত্তর পদক্ষেপ এবং বক্রতা যখন উচ্চতর হয় তখন একটি আরও সঠিক সঠিক নির্বাচন করতে পারে।


দূরে গিয়ে সমস্যার দিকে ফিরে আসার পরে আমি একটি সিম্পসনের নিয়মটি প্রয়োগ করার সিদ্ধান্ত নিয়েছি। তবে আমি কি এটি যাচাই করতে পারি যে প্রকৃতপক্ষে সম্মিলিত সিম্পসনের নিয়মের ত্রুটিটি 1 / (N ^ 4) এর সাথে সমানুপাতিক (1 / (N ^ 3) নয় আপনি নিজের উত্তরে ইঙ্গিত করেছেন)?
ব্যবহারকারী 2970116

1
আপনার পাশাপাশি সূত্র রয়েছে । প্রথমটি এবং দ্বিতীয় । 1/N31/N45/12,13/12,1,1...1,1,13/12,15/121/3,4/3,2/3,4/3...
ডেভিডম

9

সম্ভাবনা হ'ল ফাংশনগুলির মূল্যায়ন এই গণনার সর্বাধিক সময় গ্রহণকারী অংশ। যদি এটি হয় তবে ইন্টিগ্রেশন রুটিন নিজেই গতি বাড়ানোর চেষ্টা না করে আপনার ফানক () এর গতি উন্নত করার দিকে মনোযোগ দেওয়া উচিত।

ফানক () এর বৈশিষ্ট্যগুলির উপর নির্ভর করে, সম্ভবত আপনি আরও পরিশীলিত ইন্টিগ্রেশন সূত্র ব্যবহার করে কম ফাংশন মূল্যায়নের সাথে ইন্টিগ্রালের আরও সুনির্দিষ্ট মূল্যায়ন পেতে পারেন।


1
প্রকৃতপক্ষে. যদি আপনার ফাংশনটি মসৃণ হয় তবে আপনি সাধারণত 50 টিরও কম ফাংশন মূল্যায়নের সাথে দূরে সরে যেতে পারেন যদি আপনি বলে থাকেন, কেবল 5 বিরতিতে গাউস -4 চতুর্ভুজ রুল।
ওল্ফগ্যাং ব্যাঙ্গার্থ

7

সম্ভব? হ্যাঁ. কাজে লাগল? না। আমি এখানে যে অপটিমাইজেশনগুলি তালিকা করতে যাচ্ছি তা রানটাইমের তুলনায় সামান্য পার্থক্যের একটি ক্ষুদ্র ভগ্নাংশের চেয়ে বেশি করার সম্ভাবনা নেই। একটি ভাল সংকলক ইতিমধ্যে আপনার জন্য এটি করতে পারে।

যাইহোক, আপনার অভ্যন্তরীণ লুপটি দেখুন:

    for (s=0,j=a;j<b;j+=h){
        func2 = func(j+h);
        s = s + 0.5*(func1+func2)*h;
        func1 = func2;
    }

প্রতিটি লুপ পুনরাবৃত্তিতে আপনি তিনটি গণিত ক্রিয়াকলাপ সম্পাদন করেন যা বাইরে আনা যায়: সংযোজন j + h, দ্বারা 0.5গুণ এবং দ্বারা গুণফল h। প্রথমে আপনি আপনার পুনরুক্তি পরিবর্তনশীলটি শুরু করে a + hএবং অন্যান্যগুলি গুণকগুলি বের করে ঠিক করতে পারেন :

    for (s=0, j=a+h; j<=b; j+=h){
        func2 = func(j);
        s += func1+func2;
        func1 = func2;
    }
    s *= 0.5 * h;

যদিও আমি এটি উল্লেখ করব যে এটি করে, ভাসমান পয়েন্ট রাউন্ডঅফ ত্রুটির কারণে লুপের শেষ পুনরাবৃত্তিটি মিস করা সম্ভব। (এটি আপনার আসল বাস্তবায়নের ক্ষেত্রেও একটি সমস্যা ছিল)) এটি পেতে, একটি unsigned intবা size_tকাউন্টার ব্যবহার করুন :

    size_t n;
    for (s=0, n=0, j=a+h; n<N; n++, j+=h){
        func2 = func(j);
        s += func1+func2;
        func1 = func2;
    }
    s *= 0.5 * h;

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


4

আমি গণনা উন্নত করার জন্য সুপারিশ করব বিভিন্ন পরিবর্তন:

  • কর্মক্ষমতা এবং নির্ভুলতার জন্য, ব্যবহার করুন std::fma(), যা একটি ফিউজড মাল্টিপল-অ্যাড সম্পাদন করে ।
  • পারফরম্যান্সের জন্য, প্রতিটি ট্র্যাপিজয়েডের ক্ষেত্রফলকে 0.5 দ্বারা গুণিত করুন - আপনি একবারে এটি করতে পারেন।
  • বারবার সংযোজন এড়িয়ে চলুন h, যা রাউন্ড-অফ ত্রুটিগুলি সংগ্রহ করতে পারে।

এছাড়াও, আমি স্বচ্ছতার জন্য বেশ কয়েকটি পরিবর্তন করব:

  • ফাংশনটির আরও বর্ণনামূলক নাম দিন।
  • ক্রম অদল-বদল abফাংশন স্বাক্ষরে।
  • পুনরায় নামকরণ Nn, hdx, jx2, saccumulator
  • একটিতে পরিবর্তন nকরুন int
  • একটি শক্ত সুযোগে ভেরিয়েবলগুলি ঘোষণা করুন।
#include <cmath>

double trapezoidal_integration(double func(double), double a, double b, int n) {
    double dx = (b - a) / (n - 1);   // Width of trapezoids

    double func_x1 = func(a);
    double accumulator = 0;

    for (int i = 1; i <= n; i++) {
        double x2 = a + i * dx;      // Avoid repeated floating-point addition
        double func_x2 = func(x2);
        accumulator = std::fma(func_x1 + func_x2, dx, accumulator); // Fused multiply-add
        func_x1 = func_x2;
    }

    return 0.5 * accumulator;
}

3

যদি আপনার ফাংশনটি একটি বহুবর্ষীয় হয়, সম্ভবত কোনও ফাংশন দ্বারা ভারিত (যেমন গাউসিয়ান), আপনি একটি ঘন সূত্রের সাহায্যে সরাসরি 3 ডি-তে সঠিক সংহতকরণ করতে পারেন (উদাঃ http://people.sc.fsu.edu/~jburkardt/c_src/ Stroud / stroud.html ) অথবা একটি বিক্ষিপ্ত গ্রিড সঙ্গে (যেমন http://tasmanian.ornl.gov/ )। এই পদ্ধতিগুলি দ্বারা ফাংশনের মান দ্বারা গুণিত করতে পয়েন্ট এবং ওজনের একটি সেট নির্দিষ্ট করে, তাই এগুলি খুব দ্রুত। যদি আপনার ফাংশনটি বহুবচন অনুসারে প্রায় স্বচ্ছ হয় তবে এই পদ্ধতিগুলি এখনও খুব ভাল উত্তর দিতে পারে। সূত্রগুলি আপনি সংহত করছেন এমন ফাংশনটির জন্য বিশেষীকরণ করা হয়েছে, সুতরাং সঠিকটি খুঁজে পেতে এটি খনন করতে পারে।


3

আপনি যখন অবিচ্ছেদ্য সংখ্যাসূচকভাবে গণনা করার চেষ্টা করেন, আপনি সর্বনিম্নতম চেষ্টা সহ যে বিকল্পটি চান তা পেতে চেষ্টা করেন বা বিকল্পভাবে, একটি নির্দিষ্ট প্রচেষ্টা দিয়ে সর্বোচ্চ সম্ভাব্য নির্ভুলতা পাওয়ার চেষ্টা করুন। আপনি মনে করছেন যে কোনও একটি নির্দিষ্ট অ্যালগরিদমের কোডটি কীভাবে সম্ভব দ্রুত চালানো যায় ask

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


3

ইন্টিগ্রেশন করার প্রচুর উপায় রয়েছে যার মধ্যে ট্র্যাপিজয়েডাল নিয়মটি সবচেয়ে সহজ।

আপনি যে প্রকৃত ফাংশনটি সংহত করছেন সে সম্পর্কে আপনি যদি কিছু কিছু জানেন তবে আপনি যদি এটি কাজে লাগান তবে আপনি আরও ভাল করতে পারেন। ধারণাটি হ'ল ত্রুটির গ্রহণযোগ্য স্তরের মধ্যে গ্রিড পয়েন্টগুলির সংখ্যা হ্রাস করা।

উদাহরণস্বরূপ, ট্র্যাপিজয়েডাল একটানা পয়েন্টে লিনিয়ার ফিট করে চলেছে। আপনি একটি চতুর্ভুজ ফিট করতে পারেন, যা যদি বক্রটি মসৃণ হয় তবে এটি আরও ভাল ফিট করতে পারে, যা আপনাকে মোটা গ্রিড ব্যবহার করতে দেয়।

অরবিটাল সিমুলেশনগুলি কখনও কখনও শঙ্কু ব্যবহার করে করা হয়, কারণ কক্ষপথ অনেকটা শঙ্কু বিভাগের মতো।

আমার কাজে, আমরা আকারগুলি আনুমানিক বেল-আকৃতির বক্ররেখাকে একীভূত করছি, সুতরাং তাদের মডেল করা কার্যকর যে ( অভিযোজিত গাউসিয়ান চতুর্ভুজটিকে এই কাজে "স্বর্ণের মান" হিসাবে বিবেচনা করা হয়)।


1

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

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

এটি উচ্চ মাত্রিক ডেটার জন্য অত্যন্ত কার্যকরভাবে কাজ করে, সাধারণত 1-ডি সংহতকরণে ব্যবহৃত চতুর্ভুজ পদ্ধতিগুলির চেয়ে অনেক ভাল।

সাধারণ ক্ষেত্রে প্রয়োগ করা খুব সহজ (পিডিএফ দেখুন), কেবল সতর্কতা অবলম্বন করুন যে সি ++ 98 এর স্ট্যান্ডার্ড র্যান্ডম ফাংশনটি পারফরম্যান্স এবং মানের দিক থেকে উভয়ই যথেষ্ট খারাপ। সি ++ 11 এ আপনি মরসেন টুইস্টার ইন ব্যবহার করতে পারেন।

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


1
আমি আসলে একটি 3D সংহত করছি, যেখানে এই কোডটি পুনরাবৃত্তভাবে বলা হয়।

"পুনরাবৃত্তিমূলকভাবে" চাবিকাঠি। আপনি হয় একটি বৃহত ডেটা সেট দিয়ে যাচ্ছেন এবং একাধিকবার ডেটা বিবেচনা করছেন, বা আপনি আসলে (ডেটাওয়াইজ?) ফাংশন থেকে নিজেকে উপাত্ত সেট করে নিজের ডেটা তৈরি করছেন।

পুনরাবৃত্তির সাথে মূল্যায়ন করা সংহতগুলি হাস্যকরভাবে ব্যয়বহুল হবে এবং পুনরাবৃত্তির ক্ষমতা বৃদ্ধি পাওয়ার সাথে সাথে হাস্যকরভাবে অসম্পূর্ণ হবে।

আপনার ডেটা সেটটি ইন্টারপোলেটিংয়ের জন্য একটি মডেল তৈরি করুন এবং টুকরা দিকের প্রতীকী ইন্টিগ্রেশন করুন। যেহেতু প্রচুর ডেটা তখন বেস ফাংশনগুলির সহগগুলিতে বিপর্যস্ত হচ্ছে, গভীর পুনরাবৃত্তির জন্য জটিলতা তাত্পর্যপূর্ণ হওয়ার পরিবর্তে বহুপদী (এবং সাধারণত কম শক্তিগুলি) বৃদ্ধি পায়। এবং আপনি "সঠিক" ফলাফল পান (যুক্তিসঙ্গত সংখ্যার পারফরম্যান্স পাওয়ার জন্য আপনাকে এখনও ভাল মূল্যায়ন প্রকল্পগুলি খুঁজে বের করতে হবে তবে ট্র্যাপিজয়েডাল ইন্টিগ্রেশনের চেয়ে আরও ভাল হওয়ার পক্ষে এটি সম্ভবত সম্ভাব্য হওয়া উচিত)।

আপনি যদি ট্র্যাপিজয়েডাল বিধিগুলির জন্য ত্রুটি অনুমানের দিকে একবার নজর দেন তবে আপনি দেখতে পাবেন যে এগুলি জড়িত কার্যাবলীর কিছু অনুজাতের সাথে সম্পর্কিত, এবং যদি সংহতকরণ / সংজ্ঞাটি পুনরাবৃত্তভাবে করা হয়, তবে ফাংশনগুলি ভাল-আচরণযুক্ত ডেরিভেটিভসকে ঝোঁক করে না ।

যদি আপনার একমাত্র হাতিয়ার হাতুড়ি হয় তবে প্রতিটি সমস্যা পেরেকের মতো লাগে। আপনি সবে আপনার বর্ণনার মধ্যে সমস্যা উপর স্পর্শ করার সময়, আমি সন্দেহ trapezoidal নিয়ম প্রয়োগ আছে যাও recursively একটি খারাপ ম্যাচ হল: আপনি উভয় ভ্রম এবং গণনীয় প্রয়োজনীয়তা একটি বিস্ফোরণ পেতে।


1

মূল কোড প্রতিটি এন পয়েন্টে ফাংশনটি মূল্যায়ন করে, তারপরে মানগুলিকে যুক্ত করে এবং ধাপের আকার দ্বারা যোগফলকে গুণ করে। কেবল কৌশলটি হ'ল প্রথম এবং শেষের মানগুলি ওজন সহ যুক্ত করা হয় , তবে অভ্যন্তরের সমস্ত পয়েন্টগুলি পুরো ওজনের সাথে যুক্ত হয়। আসলে, এগুলি ওজন তবে দু'বার যুক্ত করা হয় added এগুলিকে দুবার যুক্ত করার পরিবর্তে, একবারে পুরো ওজনের সাথে যুক্ত করুন। লুপের বাইরে ধাপের আকার দ্বারা গুণনটি তৈরি করুন। সত্যিই, এটির গতি বাড়ানোর জন্য যা কিছু করা যায়।1/21/2

    double trap(double func(double), double b, double a, double N){
double j, s;
double h = (b-a)/(N-1.0); //Width of trapezia

double s = 0;
j = a;
for(i=1; i<N-1; i++){
  j += h;
  s += func(j);
}
s += (func(a)+func(b))/2;

return s*h;
}

1
আপনার পরিবর্তন এবং কোড জন্য যুক্তি দিন দয়া করে। কোডের একটি ব্লক বেশিরভাগ মানুষের পক্ষে মোটামুটি অকেজো।
গর্ড্রিক

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