বিজ্ঞপ্তি তথ্যগুলির সেটগুলির গড় আপনি কীভাবে গণনা করবেন?


147

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

আসল প্রশ্নটি আরও জটিল - পরিসংখ্যানগুলির অর্থ কোনও গোলক বা একটি বীজগণিতীয় জায়গার অর্থ যা "চারপাশে মোড়ানো", যেমন অ্যাডিটিভ গ্রুপ মোড এন। উত্তরটি অনন্য হতে পারে না, উদাহরণস্বরূপ, 359 ডিগ্রি এবং 1 ডিগ্রি গড়ে 0 ডিগ্রি বা 180 হতে পারে তবে পরিসংখ্যানগত দিক থেকে 0 আরও ভাল দেখাচ্ছে।

এটি আমার জন্য একটি বাস্তব প্রোগ্রামিং সমস্যা এবং আমি চেষ্টা করছি এটি কেবল একটি গণিত সমস্যার মতো দেখায় না।


1
গড় কোণ অনুসারে, আমি ধরে নিই যে আপনার আসল অর্থটি ভারবহন করতে চান। একটি কোণ দুটি লাইনের মধ্যে বিদ্যমান, একটি ভারবহন একক লাইনের দিক। এই ক্ষেত্রে, স্টার ব্লু এটি ঠিক আছে।
SmacL

@ নিক ফরটস্কিউ: আপনার প্রশ্নটি আরও সুনির্দিষ্ট করার জন্য আপডেট করতে পারবেন: আপনার কোণ বা ভারবহন বলতে কী বোঝায়?
মিচ গম

1
আমি আসলে কিছুটা জটিল জিনিস চেয়েছিলাম (তবে এটি বিয়ারিংয়ের সাথে সাদৃশ্যপূর্ণ) এবং প্রশ্নটি আরও সহজ করার জন্য সহজ করার চেষ্টা করছিলাম এবং যথারীতি এটি আরও জটিল করে তুলেছে। আমি যে উত্তরটি চেয়েছিলাম তা আমি catless.ncl.ac.uk/Risks/7.44.html#subj4পেয়েছি । আমি কিউএনটি পুনরায় সম্পাদনা করব।
নিক ফোর্টসেকু

ঝুঁকির উত্তরটি মূলত আমি যা প্রস্তাব করছি তা হ'ল, ডিনোমিনেটর 0 হলে সমস্যাটি হতে পারে
স্টার ব্লু

কোণগুলির অর্থের সাথে আকর্ষণীয় নিবন্ধ: twistedoakstudios.com/blog/?p=938
স্টারব্লু

উত্তর:


99

কোণ থেকে ইউনিট ভেক্টরগুলি গণনা করুন এবং তাদের গড়ের কোণ নিন।


8
ভেক্টররা একে অপরকে বাতিল করে দিলে এটি কার্যকর হয় না। গড় তার যথার্থ সংজ্ঞা অনুসারে এই ক্ষেত্রে এখনও অর্থবহ হতে পারে।
ডেভিড হানাক

21
@ ডেভিড, 180 ডিগ্রি আউট দুটি বিয়ারিংয়ের গড় দিক নির্ধারিত। এটি স্টার ব্লুয়ের উত্তরটিকে ভুল করে না, এটি কেবল একটি ব্যতিক্রমী ঘটনা, যেমনটি অনেক ভূতাত্ত্বিক সমস্যায় দেখা যায়।
স্মার্টL

5
@ স্মাকাল: আমি সম্মতি জানাই, যদি কোণ নির্দেশাবলী উপস্থাপন করে। তবে আপনি যদি জটিল সংখ্যার কথা ভাবেন, উদাহরণস্বরূপ এবং গড়কে "গ এর আর্গুমেন্ট কী, যেমন সি সি == এ বি" হিসাবে নির্ধারণ করেন, যেখানে a এবং b এর 1 এর মডুলাস রয়েছে, তবে গড়ে 0 এবং 180 এর গড় 90.
ডেভিড হানাক


5
@ পিয়ারবিডিআর: আমি যদি 0 ডিগ্রি দিকের দিকে এবং একটি 90 ডিগ্রি দিকের দুটি পদক্ষেপ নিয়ে যাই তবে আমি যেদিকে শুরু করেছি তার তুলনায় 26.56 ডিগ্রি অগ্রসর হয়ে যাব। এই অর্থে 26.56 30 ডিগ্রির চেয়ে 0,0,90} ডিগ্রি গড় গড় দিক হিসাবে আরও বেশি বোঝায়। বীজগণিতের গড়গুলি সম্ভাব্য গড়গুলির মধ্যে একটি মাত্র (দেখুন en.wikedia.org/wiki/Mean ) - এবং এটি গড় দিকনির্দেশের উদ্দেশ্যে (যেমন এটি অন্য অনেকের পক্ষে হয়) বেশ অপ্রাসঙ্গিক বলে মনে হয়।
জানুস

60

এই প্রশ্নটি বইটিতে বিশদভাবে পরীক্ষা করা হয়: "স্ট্যাটিস্টিক্স অন স্পিরিস", জেফ্রি এস ওয়াটসন, আরকানসাস লেকচার নোটস অফ ম্যাথমেটিকাল সায়েন্সেস, 1983 জন উইলে অ্যান্ড সন্স, ইনক । ac.uk/Risks/7.44.html#subj4 ব্রুস কার্শ লিখেছেন

একটি কোণ পরিমাপের একটি সেট থেকে একটি গড় কোণ, A অনুমান করার একটি ভাল উপায় a [i] 0 <= i

                   sum_i_from_1_to_N sin(a[i])
a = arctangent ---------------------------
                   sum_i_from_1_to_N cos(a[i])

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

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


8
যা আমি আপনার সময়ে একই সময়ে পোস্ট করা অ্যালগরিদমের মতো একই। আপনি যেহেতু অন্যথায় তোমাকে বলতে পারবো না যা পাদ উত্তর হয়, ATAN2 বরং একটি প্লেইন ATAN চেয়ে, যদিও ব্যবহার করার প্রয়োজন হবে।
ঊষা

আপনি এখনও কিছু অনির্দিষ্ট উত্তর দিয়ে শেষ করতে পারেন। 0, 180 নমুনায় পছন্দ করুন। সুতরাং আপনি এখনও প্রান্ত ক্ষেত্রে জন্য পরীক্ষা করতে হবে। এছাড়াও, সাধারণত একটি অ্যাটান 2 উপলব্ধ থাকে যা আপনার ক্ষেত্রে দ্রুত হতে পারে।
লোকি

50

আমি সমস্যাটি দেখতে পাচ্ছি - উদাহরণস্বরূপ, আপনার যদি 45 'কোণ এবং 315' কোণ থাকে তবে "প্রাকৃতিক" গড় 180 হবে, তবে আপনি যে মানটি চান তা আসলে 0 '।

আমি মনে করি স্টারব্লু কোনও কিছুর উপরে। প্রতিটি কোণের জন্য কেবল (x, y) কার্টেসিয়ান স্থানাঙ্কগুলি গণনা করুন এবং ফলস্বরূপ ভেক্টরগুলিকে একসাথে যুক্ত করুন। চূড়ান্ত ভেক্টরের কৌনিক অফসেটটি আপনার প্রয়োজনীয় ফলাফল হওয়া উচিত।

x = y = 0
foreach angle {
    x += cos(angle)
    y += sin(angle)
}
average_angle = atan2(y, x)

আমি আপাতত এড়িয়ে যাচ্ছি যে একটি কম্পাস শিরোনাম উত্তরে শুরু হয়, এবং ঘড়ির কাঁটার দিকে চলে যায়, যেখানে "সাধারণ" কার্টেসিয়ান স্থানাঙ্কগুলি X অক্ষ বরাবর শূন্য দিয়ে শুরু হয় এবং তারপরে ঘড়ির কাঁটার বিপরীতে চলে যায়। গণিতের নির্বিশেষে একইভাবে কাজ করা উচিত।


13
আপনার গণিতের গ্রন্থাগারটি সম্ভবত কোণগুলির জন্য রেডিয়ান ব্যবহার করে। রূপান্তর মনে রাখবেন।
মার্টিন বেকেট

2
হয়তো রাত্রে অনেক দেরি হয়ে গেছে, তবে এই যুক্তিটি ব্যবহার করে, আমি [320, 330, 340, 350, 10,] এর কোণগুলির 342 এর পরিবর্তে 341.8947 এর গড় কোণ পেয়ে যাচ্ছি। আমার টাইপো কেউ দেখে?
অ্যালেক্স রবিনসন

1
@ অ্যালেক্সরবিনসন এটি কোনও টাইপো নয়, কারণ চূড়ান্ত কোণটি স্বতন্ত্রভাবে সেই প্রতিটি কোণগুলির একটি সেট গ্রহণ করে প্রাপ্ত চূড়ান্ত কোণ।
Alnitak

1
@AlexRobinson, আরো নির্দিষ্ট হতে হবে: cos(), sin()এবং atan2()অনুমান দিতে (ভাল বেশী, কিন্তু এখনও 1 বা 2 ulps দ্বারা বন্ধ) যাতে আরো আপনি গড়, আরো ত্রুটি আপনি অন্তর্ভুক্ত।
ম্যাথিউউ

23

দুটি অ্যাঙ্গেলগুলির বিশেষ অবস্থার জন্য:

উত্তর ((a + b) মোড 360) / 2 হ'ল ভুল । 350 এবং 2 কোণগুলির জন্য, নিকটতম পয়েন্টটি 176 নয় 356।

ইউনিট ভেক্টর এবং ট্রিগ সমাধানগুলি খুব ব্যয়বহুল হতে পারে।

আমি একটু ঝুঁকির মধ্যে দিয়ে যা পেয়েছি তা হ'ল:

diff = ( ( a - b + 180 + 360 ) mod 360 ) - 180
angle = (360 + b + ( diff / 2 ) ) mod 360
  • 0, 180 -> 90 (এর জন্য দুটি উত্তর: এই সমীকরণটি ঘড়ির কাঁটার দিক থেকে উত্তর একটি থেকে নেয়)
  • 180, 0 -> 270 (উপরে দেখুন)
  • 180, 1 -> 90.5
  • 1, 180 -> 90.5
  • 20, 350 -> 5
  • 350, 20 -> 5 (নিম্নলিখিত সমস্ত উদাহরণ সঠিকভাবে বিপরীত)
  • 10, 20 -> 15
  • 350, 2 -> 356
  • 359, 0 -> 359.5
  • 180, 180 -> 180

এই আরও BAMS ব্যবহার দ্বারা অপ্টিমাইজ করা যেতে পারে stackoverflow.com/questions/1048945/...
darron

খারাপ না. প্রথম রেখাটি বি-এর সাথে [-180, 179] এর সাথে সম্পর্কিত একটি এর আপেক্ষিক কোণটি গণনা করে, দ্বিতীয়টি এর মধ্যবর্তী কোণটি গণনা করে। আমি স্পষ্টতার জন্য একটি - ডিফ / 2 এর পরিবর্তে বি + ডিফ / 2 ব্যবহার করব।
স্টার ব্লু

1
আমি কিছু অনুপস্থিত করছি? আমি DO পেতে 295.
darron

আহ .. আমি পেয়েছি। মতলবের মোড অপারেটর -১০ থেকে ৩৫০ পর্যন্ত মোড়কে I'll আমি কোডটি পরিবর্তন করব। এটি একটি সাধারণ অতিরিক্ত 360
ডারন

এই পদ্ধতির আর একটি দুর্দান্ত বৈশিষ্ট্য হ'ল দুটি কোণের ওজনযুক্ত গড় বাস্তবায়ন করা সহজ। দ্বিতীয় লাইনে, প্রথম কোণের ওজন দ্বারা আলাদা করে এবং 2 এর পরিবর্তককে ওজনের যোগফলের সাথে প্রতিস্থাপন করুন। কোণ = (360 + বি + (ওজন [এ] * ডিফ / /
ওয়েট

14

ackb ঠিক আছে যে এই ভেক্টর ভিত্তিক সমাধানগুলিকে সঠিক গড় হিসাবে বিবেচনা করা যায় না, এগুলি কেবলমাত্র ইউনিট ভেক্টর অংশগুলির মধ্যে একটি গড়। তবে, এসিবিবির প্রস্তাবিত সমাধান গাণিতিকভাবে শোনায় না।

নিম্নলিখিতটি একটি সমাধান যা গাণিতিকভাবে কমানোর লক্ষ্য থেকে উদ্ভূত হয়েছে (কোণ [i] - গড় অ্যাংগল) ^ 2 (যেখানে প্রয়োজনে পার্থক্যটি সংশোধন করা হয়েছে), এটি এটিকে কোণগুলির সত্যিকারের গাণিতিক গড় করে তোলে।

প্রথমত, আমাদের কোণ সংখ্যাগুলির মধ্যে পার্থক্যটি তাদের সাধারণ সংখ্যা সমকক্ষগুলির মধ্যে পার্থক্যের তুলনায় ঠিক কী ক্ষেত্রে ঠিক তা দেখতে হবে। X এবং y কোণগুলি বিবেচনা করুন, যদি y> = x - 180 এবং y <= x + 180 হয় তবে আমরা পার্থক্যটি (xy) সরাসরি ব্যবহার করতে পারি। অন্যথায়, যদি প্রথম শর্তটি পূরণ না হয় তবে আমাদের অবশ্যই y এর পরিবর্তে গণনায় (y + 360) ব্যবহার করতে হবে। অনুরূপ, দ্বিতীয় শর্তটি যদি পূরণ না হয় তবে আমাদের অবশ্যই y এর পরিবর্তে (y-360) ব্যবহার করতে হবে। যেহেতু কার্ভের সমীকরণটি আমরা কেবলমাত্র সেই পয়েন্টগুলিতে পরিবর্তনগুলি হ্রাস করছি যেখানে এই অসমতাগুলি সত্য থেকে মিথ্যা বা বিপরীতে পরিবর্তিত হয়, তাই আমরা এই পয়েন্টগুলি দ্বারা পৃথক করে পুরো [0,360) পরিসরকে বিভাগগুলির একটি সেটে আলাদা করতে পারি। তারপরে, আমাদের কেবলমাত্র এই বিভাগগুলির প্রত্যেকের ন্যূনতম এবং তারপরে প্রতিটি বিভাগের ন্যূনতম, যা গড়, তা খুঁজে বের করতে হবে।

এখানে একটি চিত্র প্রদর্শিত হচ্ছে যেখানে কোণগুলির পার্থক্য গণনা করতে সমস্যা দেখা দেয়। যদি x ধূসর জায়গায় থাকে তবে সমস্যা হবে।

কোণ তুলনা

একটি পরিবর্তনক কমানোর জন্য, বক্ররেখার উপর নির্ভর করে আমরা কী কম করতে চাই তার ডেরিভেটিভ নিতে পারি এবং তারপরে আমরা টার্নিং পয়েন্টটি পাই (যেখানে এটি ডেরিভেটিভ = 0)।

এখানে আমরা সাধারণ পাটিগণিত গড় সূত্রটি সংগ্রহ করতে বর্গক্ষেত্রের পার্থক্য হ্রাস করার ধারণাটি প্রয়োগ করব: যোগফল (একটি [i]) / এন। বক্ররেখ y = যোগফল ((a [i] -x) ^ 2) এইভাবে হ্রাস করা যেতে পারে:

y = sum((a[i]-x)^2)
= sum(a[i]^2 - 2*a[i]*x + x^2)
= sum(a[i]^2) - 2*x*sum(a[i]) + n*x^2

dy\dx = -2*sum(a[i]) + 2*n*x

for dy/dx = 0:
-2*sum(a[i]) + 2*n*x = 0
-> n*x = sum(a[i])
-> x = sum(a[i])/n

আমাদের সমন্বিত পার্থক্য সহ এটি এখন কার্ভে প্রয়োগ করুন:

খ = যেখানে একটি (কৌণিক) পার্থক্য একটি [i] -xc = উপসেট যেখানে একটি (কৌণিক) পার্থক্য (একটি [i] -360) -x সিএন = সিডি এর আকার = একটি উপসেট যেখানে সঠিক (কৌণিক) পার্থক্য (a [i] +360) -x dn = d এর আকার

y = sum((b[i]-x)^2) + sum(((c[i]-360)-b)^2) + sum(((d[i]+360)-c)^2)
= sum(b[i]^2 - 2*b[i]*x + x^2)
  + sum((c[i]-360)^2 - 2*(c[i]-360)*x + x^2)
  + sum((d[i]+360)^2 - 2*(d[i]+360)*x + x^2)
= sum(b[i]^2) - 2*x*sum(b[i])
  + sum((c[i]-360)^2) - 2*x*(sum(c[i]) - 360*cn)
  + sum((d[i]+360)^2) - 2*x*(sum(d[i]) + 360*dn)
  + n*x^2
= sum(b[i]^2) + sum((c[i]-360)^2) + sum((d[i]+360)^2)
  - 2*x*(sum(b[i]) + sum(c[i]) + sum(d[i]))
  - 2*x*(360*dn - 360*cn)
  + n*x^2
= sum(b[i]^2) + sum((c[i]-360)^2) + sum((d[i]+360)^2)
  - 2*x*sum(x[i])
  - 2*x*360*(dn - cn)
  + n*x^2

dy/dx = 2*n*x - 2*sum(x[i]) - 2*360*(dn - cn)

for dy/dx = 0:
2*n*x - 2*sum(x[i]) - 2*360*(dn - cn) = 0
n*x = sum(x[i]) + 360*(dn - cn)
x = (sum(x[i]) + 360*(dn - cn))/n

এটি এককভাবে ন্যূনতম প্রাপ্তির পক্ষে যথেষ্ট নয়, যখন এটি সাধারণ মানের জন্য কাজ করে, এতে একটি সীমাহীন সেট রয়েছে, সুতরাং ফলাফলটি অবশ্যই সেটটির সীমার মধ্যেই থাকবে এবং তাই বৈধ। আমাদের একটি পরিসরের মধ্যে ন্যূনতম প্রয়োজন (বিভাগটি দ্বারা সংজ্ঞায়িত)। যদি ন্যূনতমটি আমাদের বিভাগের নিম্ন সীমাটির চেয়ে কম হয় তবে সেগমেন্টের সর্বনিম্নটি ​​অবশ্যই নিম্ন সীমানায় থাকতে হবে (কারণ চতুর্ভুজ বক্ররেখাগুলির কেবলমাত্র 1 টি টার্নিং পয়েন্ট রয়েছে) এবং যদি ন্যূনতমটি আমাদের বিভাগের উপরের সীমানার চেয়ে বেশি হয় তবে বিভাগটির সর্বনিম্ন হয় ঊর্ধ্বসীমা. আমাদের প্রতিটি বিভাগের জন্য সর্বনিম্ন থাকার পরে, আমরা কেবলমাত্র যা হ্রাস করছি তার জন্য সর্বনিম্ন মানটি আমরা খুঁজে পাই (যোগফল ((খ [i] -x) ^ 2) + সমষ্টি ((সি [আমি] -360 ) -বি) ^ 2) + সমষ্টি (((ডি [আমি] +360) -সি) ^ 2))।

এখানে বক্ররেখাতে একটি চিত্র রয়েছে যা এটি দেখায় যে এটি কীভাবে পয়েন্টে পরিবর্তিত হয় যেখানে x = (a [i] +180)% 360। ডেটা সেটটি প্রশ্নযুক্ত {65,92,230,320,250}}

বাঁক

এখানে জাভাতে অ্যালগরিদমের একটি বাস্তবায়ন রয়েছে, যার মধ্যে কয়েকটি অপটিমাইজেশন রয়েছে, এর জটিলতা হ'ল O (nlogn)। যদি আপনি তুলনা ভিত্তিক সাজানটিকে কোনও তুলনামূলক ভিত্তিক সাজানো, যেমন র‌্যাডিক্স সাজানোর সাথে প্রতিস্থাপন করেন তবে এটি ও (এন) এ হ্রাস করা যাবে।

static double varnc(double _mean, int _n, double _sumX, double _sumSqrX)
{
    return _mean*(_n*_mean - 2*_sumX) + _sumSqrX;
}
//with lower correction
static double varlc(double _mean, int _n, double _sumX, double _sumSqrX, int _nc, double _sumC)
{
    return _mean*(_n*_mean - 2*_sumX) + _sumSqrX
            + 2*360*_sumC + _nc*(-2*360*_mean + 360*360);
}
//with upper correction
static double varuc(double _mean, int _n, double _sumX, double _sumSqrX, int _nc, double _sumC)
{
    return _mean*(_n*_mean - 2*_sumX) + _sumSqrX
            - 2*360*_sumC + _nc*(2*360*_mean + 360*360);
}

static double[] averageAngles(double[] _angles)
{
    double sumAngles;
    double sumSqrAngles;

    double[] lowerAngles;
    double[] upperAngles;

    {
        List<Double> lowerAngles_ = new LinkedList<Double>();
        List<Double> upperAngles_ = new LinkedList<Double>();

        sumAngles = 0;
        sumSqrAngles = 0;
        for(double angle : _angles)
        {
            sumAngles += angle;
            sumSqrAngles += angle*angle;
            if(angle < 180)
                lowerAngles_.add(angle);
            else if(angle > 180)
                upperAngles_.add(angle);
        }


        Collections.sort(lowerAngles_);
        Collections.sort(upperAngles_,Collections.reverseOrder());


        lowerAngles = new double[lowerAngles_.size()];
        Iterator<Double> lowerAnglesIter = lowerAngles_.iterator();
        for(int i = 0; i < lowerAngles_.size(); i++)
            lowerAngles[i] = lowerAnglesIter.next();

        upperAngles = new double[upperAngles_.size()];
        Iterator<Double> upperAnglesIter = upperAngles_.iterator();
        for(int i = 0; i < upperAngles_.size(); i++)
            upperAngles[i] = upperAnglesIter.next();
    }

    List<Double> averageAngles = new LinkedList<Double>();
    averageAngles.add(180d);
    double variance = varnc(180,_angles.length,sumAngles,sumSqrAngles);

    double lowerBound = 180;
    double sumLC = 0;
    for(int i = 0; i < lowerAngles.length; i++)
    {
        //get average for a segment based on minimum
        double testAverageAngle = (sumAngles + 360*i)/_angles.length;
        //minimum is outside segment range (therefore not directly relevant)
        //since it is greater than lowerAngles[i], the minimum for the segment
        //must lie on the boundary lowerAngles[i]
        if(testAverageAngle > lowerAngles[i]+180)
            testAverageAngle = lowerAngles[i];

        if(testAverageAngle > lowerBound)
        {
            double testVariance = varlc(testAverageAngle,_angles.length,sumAngles,sumSqrAngles,i,sumLC);

            if(testVariance < variance)
            {
                averageAngles.clear();
                averageAngles.add(testAverageAngle);
                variance = testVariance;
            }
            else if(testVariance == variance)
                averageAngles.add(testAverageAngle);
        }

        lowerBound = lowerAngles[i];
        sumLC += lowerAngles[i];
    }
    //Test last segment
    {
        //get average for a segment based on minimum
        double testAverageAngle = (sumAngles + 360*lowerAngles.length)/_angles.length;
        //minimum is inside segment range
        //we will test average 0 (360) later
        if(testAverageAngle < 360 && testAverageAngle > lowerBound)
        {
            double testVariance = varlc(testAverageAngle,_angles.length,sumAngles,sumSqrAngles,lowerAngles.length,sumLC);

            if(testVariance < variance)
            {
                averageAngles.clear();
                averageAngles.add(testAverageAngle);
                variance = testVariance;
            }
            else if(testVariance == variance)
                averageAngles.add(testAverageAngle);
        }
    }


    double upperBound = 180;
    double sumUC = 0;
    for(int i = 0; i < upperAngles.length; i++)
    {
        //get average for a segment based on minimum
        double testAverageAngle = (sumAngles - 360*i)/_angles.length;
        //minimum is outside segment range (therefore not directly relevant)
        //since it is greater than lowerAngles[i], the minimum for the segment
        //must lie on the boundary lowerAngles[i]
        if(testAverageAngle < upperAngles[i]-180)
            testAverageAngle = upperAngles[i];

        if(testAverageAngle < upperBound)
        {
            double testVariance = varuc(testAverageAngle,_angles.length,sumAngles,sumSqrAngles,i,sumUC);

            if(testVariance < variance)
            {
                averageAngles.clear();
                averageAngles.add(testAverageAngle);
                variance = testVariance;
            }
            else if(testVariance == variance)
                averageAngles.add(testAverageAngle);
        }

        upperBound = upperAngles[i];
        sumUC += upperBound;
    }
    //Test last segment
    {
        //get average for a segment based on minimum
        double testAverageAngle = (sumAngles - 360*upperAngles.length)/_angles.length;
        //minimum is inside segment range
        //we test average 0 (360) now           
        if(testAverageAngle < 0)
            testAverageAngle = 0;

        if(testAverageAngle < upperBound)
        {
            double testVariance = varuc(testAverageAngle,_angles.length,sumAngles,sumSqrAngles,upperAngles.length,sumUC);

            if(testVariance < variance)
            {
                averageAngles.clear();
                averageAngles.add(testAverageAngle);
                variance = testVariance;
            }
            else if(testVariance == variance)
                averageAngles.add(testAverageAngle);
        }
    }


    double[] averageAngles_ = new double[averageAngles.size()];
    Iterator<Double> averageAnglesIter = averageAngles.iterator();
    for(int i = 0; i < averageAngles_.length; i++)
        averageAngles_[i] = averageAnglesIter.next();


    return averageAngles_;
}

কোণগুলির একটি সেটের গাণিতিক গড়টি গড়টি কী হওয়া উচিত তা সম্পর্কে আপনার স্বজ্ঞাত ধারণার সাথে একমত হতে পারে না। উদাহরণস্বরূপ, সেটটির গাণিতিক গড়টি {179,179,0,181,181} 216 (এবং 144)। আপনি অবিলম্বে উত্তরটি 180 এর মতো বলে মনে করছেন, তবে এটি সুপরিচিত যে পাটিগণিত গড়টি প্রান্তিক মানগুলি দ্বারা খুব বেশি প্রভাবিত। আপনার এও মনে রাখা উচিত যে কোণগুলি কোনও ভেক্টর নয়, যেমনটি কখনও কখনও কোণগুলির সাথে আচরণ করার সময় মনে হয়।

এই অ্যালগরিদম অবশ্যই সমস্ত পরিমাণে প্রযোজ্য যা মডিউলার গাণিতিক (ন্যূনতম সামঞ্জস্য সহ) মান্য করে যেমন দিনের সময় হিসাবে।

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


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

6

আপনি সংজ্ঞায়িত করতে হবে গড় সঠিকভাবে আরও অনেক কিছু। দুটি কোণের নির্দিষ্ট ক্ষেত্রে, আমি দুটি পৃথক পরিস্থিতি সম্পর্কে ভাবতে পারি:

  1. "সত্য" গড়, অর্থাৎ (a + b) / 2% 360।
  2. একই অর্ধবৃত্তে অবস্থান করার সময় যে কোণটি দু'জনের মধ্যে "নির্দেশ করে, যেমন 355 এবং 5 এর জন্য এটি 0 হবে 180 হবে না this এটি করার জন্য আপনাকে দুটি কোণগুলির মধ্যে পার্থক্য 180 এর চেয়ে বড় কিনা তা পরীক্ষা করে দেখতে হবে অথবা না. যদি তা হয় তবে উপরের সূত্রটি ব্যবহারের আগে 360 দ্বারা ছোট কোণটি বৃদ্ধি করুন।

যদিও আমি দেখি না যে দ্বিতীয় বিকল্পটি আরও দুটি কোণের ক্ষেত্রে কীভাবে সাধারণীকরণ করা যায়।


প্রশ্নটি কোণগুলিকে বোঝায়, তবে এটি গড় দিক হিসাবে আরও ভালভাবে চিন্তা করা এবং এটি একটি সাধারণ নেভিগেশন সমস্যা।
SmacL

ভাল পয়েন্ট, ডেভিড। উদাহরণস্বরূপ, 180º কোণ এবং 540º কোণের গড় কত? এটি 360º বা 180º?
বাল্টিমার্ক

3
@ বাল্টিমার্ক, আমার ধারণা এটি আপনি কী করছেন তার উপর নির্ভর করে। যদি এর নেভিগেশন হয়, সম্ভবত পরে। যদি এটি অভিনব স্নোবোর্ডিং জাম্প হয়, তবে সম্ভবত পূর্বের;)
স্ম্যাকএল

সুতরাং 1 এবং 359 এর "সত্য" গড়টি (360/2)% 360 = 180 ?? আমি মনে করি না.
সেন্টে

1
@ ডিটে ইন সেন্টে: সংখ্যায় বলতে গেলে, স্পষ্টভাবে। উদাহরণস্বরূপ, যদি কোণগুলি দিকগুলি না করে পালা উপস্থাপন করে তবে 359 এবং 1 এর গড় অবশ্যই 180 হবে It's এটি সমস্ত ব্যাখ্যার বিষয়।
ডেভিড হানাক

4

সমস্ত গড়ের মতো উত্তরটি মেট্রিকের পছন্দের উপর নির্ভর করে। প্রদত্ত মেট্রিক এম এর জন্য, [1-N] কে-এর জন্য a_k এর কিছু কোণের a_k গড়ে কোণ 1_M যা স্কোয়ার দূরত্বের যোগফলকে কম করে দেয় ^ 2_M (a_M, a_k)। ভারিত গড়ের জন্য, একটিতে ওজন ডাব্লু_কে এর সমষ্টি অন্তর্ভুক্ত থাকে (যেমন সমষ্টি_ কে ডাব্লু_ কে = 1)। এটাই,

a_M = আরগ মিনিট_x যোগ_ কে ডাব্লু_ কে d ^ 2_ এম (এক্স, এ_ কে)

মেট্রিকের দুটি সাধারণ পছন্দ হ'ল ফ্রেবেনিয়াস এবং রিমান মেট্রিক্স। ফ্রোবেনিয়াস মেট্রিকের জন্য, একটি প্রত্যক্ষ সূত্র বিদ্যমান যা বৃত্তাকার পরিসংখ্যানগুলিতে গড় বহন সম্পর্কিত স্বাভাবিক ধারণার সাথে মিলিত হয়। বিশদ সম্পর্কে "ম্যানেজ এবং অ্যাভারেজিং গ্রুপের আবর্তন" দেখুন, মাহের মোখের, ম্যাট্রিক্স বিশ্লেষণ এবং অ্যাপ্লিকেশন সম্পর্কিত সিয়াম জার্নাল, খণ্ড 24, সংখ্যা 1, 2002, দেখুন,
http://link.aip.org/link/?SJMAEL/24/1/1

এখানে জিএনইউ অকটাভ ৩.২.৪ এর জন্য একটি ফাংশন রয়েছে যা গণনা করে:

function ma=meanangleoct(a,w,hp,ntype)
%   ma=meanangleoct(a,w,hp,ntype) returns the average of angles a
%   given weights w and half-period hp using norm type ntype
%   Ref: "Means and Averaging in the Group of Rotations",
%   Maher Moakher, SIAM Journal on Matrix Analysis and Applications,
%   Volume 24, Issue 1, 2002.

if (nargin<1) | (nargin>4), help meanangleoct, return, end 
if isempty(a), error('no measurement angles'), end
la=length(a); sa=size(a); 
if prod(sa)~=la, error('a must be a vector'); end
if (nargin<4) || isempty(ntype), ntype='F'; end
if ~sum(ntype==['F' 'R']), error('ntype must be F or R'), end
if (nargin<3) || isempty(hp), hp=pi; end
if (nargin<2) || isempty(w), w=1/la+0*a; end
lw=length(w); sw=size(w); 
if prod(sw)~=lw, error('w must be a vector'); end
if lw~=la, error('length of w must equal length of a'), end
if sum(w)~=1, warning('resumming weights to unity'), w=w/sum(w); end

a=a(:);     % make column vector
w=w(:);     % make column vector
a=mod(a+hp,2*hp)-hp;    % reduce to central period
a=a/hp*pi;              % scale to half period pi
z=exp(i*a); % U(1) elements

% % NOTA BENE:
% % fminbnd can get hung up near the boundaries.
% % If that happens, shift the input angles a
% % forward by one half period, then shift the
% % resulting mean ma back by one half period.
% X=fminbnd(@meritfcn,-pi,pi,[],z,w,ntype);

% % seems to work better
x0=imag(log(sum(w.*z)));
X=fminbnd(@meritfcn,x0-pi,x0+pi,[],z,w,ntype);

% X=real(X);              % truncate some roundoff
X=mod(X+pi,2*pi)-pi;    % reduce to central period
ma=X*hp/pi;             % scale to half period hp

return
%%%%%%

function d2=meritfcn(x,z,w,ntype)
x=exp(i*x);
if ntype=='F'
    y=x-z;
else % ntype=='R'
    y=log(x'*z);
end
d2=y'*diag(w)*y;
return
%%%%%%

% %   test script
% % 
% % NOTA BENE: meanangleoct(a,[],[],'R') will equal mean(a) 
% % when all abs(a-b) < pi/2 for some value b
% % 
% na=3, a=sort(mod(randn(1,na)+1,2)-1)*pi;
% da=diff([a a(1)+2*pi]); [mda,ndx]=min(da);
% a=circshift(a,[0 2-ndx])    % so that diff(a(2:3)) is smallest
% A=exp(i*a), B1=expm(a(1)*[0 -1; 1 0]), 
% B2=expm(a(2)*[0 -1; 1 0]), B3=expm(a(3)*[0 -1; 1 0]),
% masimpl=[angle(mean(exp(i*a))) mean(a)]
% Bsum=B1+B2+B3; BmeanF=Bsum/sqrt(det(Bsum)); 
% % this expression for BmeanR should be correct for ordering of a above
% BmeanR=B1*(B1'*B2*(B2'*B3)^(1/2))^(2/3);
% mamtrx=real([[0 1]*logm(BmeanF)*[1 0]' [0 1]*logm(BmeanR)*[1 0]'])
% manorm=[meanangleoct(a,[],[],'F') meanangleoct(a,[],[],'R')]
% polar(a,1+0*a,'b*'), axis square, hold on
% polar(manorm(1),1,'rs'), polar(manorm(2),1,'gd'), hold off

%     Meanangleoct Version 1.0
%     Copyright (C) 2011 Alphawave Research, robjohnson@alphawaveresearch.com
%     Released under GNU GPLv3 -- see file COPYING for more info.
%
%     Meanangle is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 3 of the License, or (at
%     your option) any later version.
%
%     Meanangle is distributed in the hope that it will be useful, but
%     WITHOUT ANY WARRANTY; without even the implied warranty of
%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
%     General Public License for more details.
%
%     You should have received a copy of the GNU General Public License
%     along with this program.  If not, see `http://www.gnu.org/licenses/'.

4

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

  1. প্রথম ভারবহনটি 270-360 বা 0-90 ডিগ্রি (উত্তরের দুটি চতুর্ভুজ) হয় কিনা তা পরীক্ষা করুন
  2. যদি তা হয় তবে সমস্ত মান 0 <= বিয়ারিং <360 মধ্যে রেখে এটিকে এবং পরবর্তী সমস্ত পাঠকে 180 ডিগ্রি করে আবর্তিত করুন Otherwise
  3. একবার 10 টি পাঠ নেওয়া হয়ে গেলে এমন গণনাটি সংখ্যার গড় গণনা করুন যে ধরে নেওয়া যাচ্ছে যে কোনও মোড়ক নেই
  4. যদি 180 ডিগ্রি ঘূর্ণন কার্যকর হয় তবে গণনার গড় 180 ডিগ্রি ঘোরান একটি "সত্য" ভারবহন ফিরে পেতে।

এটি আদর্শ নয়; এটি ভেঙে যেতে পারে আমি এক্ষেত্রে এটির সাথে পালিয়ে গিয়েছিলাম কারণ ডিভাইসটি কেবল খুব আস্তে আবর্তিত হয়। অন্য কেউ যদি অনুরূপ বিধিনিষেধের আওতায় নিজেকে কাজ করে দেখেন তবে আমি এটি সেখানে রেখে দেব।


3

ইংরেজীতে:

  1. 180 দ্বারা স্থানান্তরিত সমস্ত কোণ সহ একটি দ্বিতীয় ডেটা সেট করুন।
  2. উভয় ডেটা সেটের বৈকল্পিকতা নিন।
  3. সবচেয়ে ছোট বৈকল্পিকের সাথে সেট করা ডেটার গড় ধরুন।
  4. যদি এই গড়টি স্থানান্তরিত সেট থেকে হয় তবে 180 এর মধ্যে আবার উত্তরটি স্থানান্তর করুন।

অজগরে:

একটি # সংখ্যাগুরু এনএক্স 1 অ্যারে

if np.var(A) < np.var((A-180)%360):
    average = np.average(A)

else:
    average = (np.average((A-180)%360)+180)%360

এটি ট্রিগ ফাংশন ছাড়াই শেষ ফলাফল অর্জনের দুর্দান্ত উপায়, এটি কার্যকর এবং কার্যকর করা সহজ।
ইয়ান মেরার

এটি কোনও বিজ্ঞপ্তি তথ্য পরিসীমা জন্য কাজ করে; অর্ধবৃত্তাকার পরিসীমা দ্বারা স্থানান্তর; দুর্দান্ত উত্তর!
ক্যাপ্টেন ফ্যান্টাস্টিক

3

এখানে সম্পূর্ণ সমাধানটি দেওয়া হয়েছে: (ইনপুটটি ডিগ্রিতে বিয়ারিংয়ের একটি অ্যারে (0-360)

public static int getAvarageBearing(int[] arr)
{
    double sunSin = 0;
    double sunCos = 0;
    int counter = 0;

    for (double bearing : arr)
    {
        bearing *= Math.PI/180;

        sunSin += Math.sin(bearing);
        sunCos += Math.cos(bearing);
        counter++; 
    }

    int avBearing = INVALID_ANGLE_VALUE;
    if (counter > 0)
    {
        double bearingInRad = Math.atan2(sunSin/counter, sunCos/counter);
        avBearing = (int) (bearingInRad*180f/Math.PI);
        if (avBearing<0)
            avBearing += 360;
    }

    return avBearing;
}

এই সমস্যাটি আমাকে কিছুক্ষণের জন্য বিস্মিত করেছে, আপনার সমাধানগুলি কাজ করে (আরডুইনো ব্যবহার করে, আপনার কোডে কয়েকটি পরিবর্তন তবে বেশি কিছুই নয়), আমি প্রতি 50 মিমি কম্পাস রিডিং এবং রিডিং গ্রহণ করছি এবং 16 এক্স রিডিং অ্যারেতে সংরক্ষণ করছি, যা আমি তার পরে ব্যবহার করি উপরের আপনার ফাংশনে, 0-360 মোড়ের ইস্যুটি প্রায় সমাধান করা হয়েছে! ধন্যবাদ :)
অ্যান্ডোলজি

3

পাইথনে, [-180, 180) এর মধ্যে কোণ সহ

def add_angles(a, b):
  return (a + b + 180) % 360 - 180

def average_angles(a, b):
  return add_angles(a, add_angles(-a, b)/2)

বিবরণ:

গড় জন্য দুই কোণ দুটি গড় 180 ° পৃথক্, কিন্তু আমরা কাছাকাছি গড় চাইতে পারেন।

দৃশ্যরূপে, নীল (গড় ) এবং সবুজ ( একটি ) উৎপাদনের বালি হাঁস পয়েন্ট:

মূল

কোণগুলি 'মোড়কের চারপাশে' (উদাঃ 355 + 10 = 5) তবে মানক গাণিতিকগুলি এই শাখাগুলিকে উপেক্ষা করবে। তবে কোণ খটি শাখা পয়েন্টের বিপরীতে থাকলে, ( b + g ) / 2 নিকটতম গড় দেয়: টিল বিন্দু।

যে কোনও দুটি কোণের জন্য, আমরা সমস্যাটি ঘুরতে পারি তাই কোণগুলির একটি শাখা পয়েন্টের বিপরীতে থাকে, স্ট্যান্ডার্ড গড় সম্পাদন করে তারপরে ফিরে ঘোরান।

আবর্তিতফেরৎ


2

আমি জটিল সংখ্যা ব্যবহার করে ভেক্টর পথে যাব। আমার উদাহরণ পাইথনে, এতে অন্তর্নির্মিত জটিল সংখ্যা রয়েছে:

import cmath # complex math

def average_angle(list_of_angles):

    # make a new list of vectors
    vectors= [cmath.rect(1, angle) # length 1 for each vector
        for angle in list_of_angles]

    vector_sum= sum(vectors)

    # no need to average, we don't care for the modulus
    return cmath.phase(vector_sum)

দ্রষ্টব্য যে পাইথনকে ভ্যাক্টরের অস্থায়ী নতুন তালিকা তৈরি করার দরকার নেই , উপরের সমস্তগুলি এক ধাপে করা যেতে পারে; আমি অন্যান্য ভাষাগুলিতেও প্রযোজ্য আনুমানিক সিউডো কোডটিতে এই পথটি বেছে নিয়েছি।


2

এখানে একটি সম্পূর্ণ সি ++ সমাধান রয়েছে:

#include <vector>
#include <cmath>

double dAngleAvg(const vector<double>& angles) {
    auto avgSin = double{ 0.0 };
    auto avgCos = double{ 0.0 };
    static const auto conv      = double{ 0.01745329251994 }; // PI / 180
    static const auto i_conv    = double{ 57.2957795130823 }; // 180 / PI
    for (const auto& theta : angles) {
        avgSin += sin(theta*conv);
        avgCos += cos(theta*conv);
    }
    avgSin /= (double)angles.size();
    avgCos /= (double)angles.size();
    auto ret = double{ 90.0 - atan2(avgCos, avgSin) * i_conv };
    if (ret<0.0) ret += 360.0;
    return fmod(ret, 360.0);
}

এটি কোণগুলি ডাবলসের ভেক্টরের আকারে নিয়ে যায় এবং গড়টি কেবল দ্বিগুণ হিসাবে দেয়। কোণগুলি অবশ্যই ডিগ্রিতে থাকতে হবে এবং অবশ্যই গড় ডিগ্রিতেও।


avgCosx উপাদানগুলির avgSinগড়, এবং y উপাদানগুলির গড়। আর্টাক্যানজেন্ট ফাংশনের প্যারামিটারগুলি হ'ল atan2( y, x )। সুতরাং, আপনার কোডটি পরিবর্তে হওয়া উচিত নয়: atan2( avgSin, avgCos ) ??
মাইক ফিঞ্চ

আমি এই অ্যালগরিদমটি কোথাও থেকে পেয়েছি, আমি নিজেই এটি নিয়ে আসিনি, তাই আমি ধরে নিলাম এটি এটি ঠিকঠাকভাবেই সঠিক। এছাড়াও এটি সঠিক ফলাফল দেয়।
adam10603

2

অ্যালনিটকের উত্তরের ভিত্তিতে , আমি একাধিক কোণের গড় গণনা করার জন্য একটি জাভা পদ্ধতি লিখেছি:

যদি আপনার কোণগুলি রেডিয়ানে থাকে:

public static double averageAngleRadians(double... angles) {
    double x = 0;
    double y = 0;
    for (double a : angles) {
        x += Math.cos(a);
        y += Math.sin(a);
    }

    return Math.atan2(y, x);
}

যদি আপনার কোণগুলি ডিগ্রীতে থাকে:

public static double averageAngleDegrees(double... angles) {
    double x = 0;
    double y = 0;
    for (double a : angles) {
        x += Math.cos(Math.toRadians(a));
        y += Math.sin(Math.toRadians(a));
    }

    return Math.toDegrees(Math.atan2(y, x));
}

1

এখানে একটি ধারণা রয়েছে: সর্বদা ওজন ধরে রেখে একসাথে নিকটে থাকা কোণগুলির গড় গণনা করে গড় পুনরুক্তি তৈরি করুন।

আরেকটি ধারণা: প্রদত্ত কোণগুলির মধ্যে বৃহত্তম ব্যবধানটি সন্ধান করুন। দ্বিখণ্ডিত বিন্দুটি সন্ধান করুন এবং তারপরে গড় গণনা করতে রেফারেন্স শূন্য হিসাবে বৃত্তের বিপরীত বিন্দুটি চয়ন করুন।


আমি আমার উত্তরটি সুপারিশ করি না, তবে পরিবর্তে স্টারব্লিউর উচ্চমানের উত্তর। সেখানে মূল পর্যবেক্ষণটি হ'ল কম্পাসের কেন্দ্রটিকে 0,0 পয়েন্ট হিসাবে ভাবতে হবে।
জন ওয়াফেলের সাথে জন

1

আসুন বৃত্তের পরিধি সম্পর্কে পয়েন্টগুলি সহ এই কোণগুলি উপস্থাপন করুন।

আমরা কি ধরে নিতে পারি যে এই সমস্ত পয়েন্টগুলি বৃত্তের একই অর্ধেকের উপর পড়ে? (অন্যথায়, "গড় কোণ" সংজ্ঞায়নের কোনও সুস্পষ্ট উপায় নেই। ব্যাসের দুটি বিন্দুর কথা চিন্তা করুন, যেমন 0 ডিগ্রি এবং 180 ডিগ্রি --- গড় 90 ডিগ্রি বা 270 ডিগ্রি হয়? আমাদের 3 বা তার বেশি হলে কী হয়? সমানভাবে পয়েন্ট ছড়িয়ে?)

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


1

কোনও একক "সঠিক উত্তর" নেই। আমি পুঙ্খানুপুঙ্খ বিশ্লেষণের জন্য কেভি মারদিয়া এবং পিই জুপ, "নির্দেশিক পরিসংখ্যান", (উইলি, 1999) পড়ার পরামর্শ দিচ্ছি।


1

(অনুমানের তত্ত্ব বা পরিসংখ্যানগত অনুমান থেকে কেবল আমার দৃষ্টিভঙ্গি ভাগ করতে চাই)

নিম্বলের পরীক্ষাটি এমএমএসই ang কোণগুলির একটি সেটের অনুমান পাওয়া, তবে এটি একটি "গড়" দিকনির্দেশ অনুসন্ধান করার পছন্দগুলির মধ্যে একটি; একজন এমএমএই-এর অনুমান বা "গড়" দিক হতে পারে এমন কিছু অনুমানও খুঁজে পেতে পারে এবং এটি আপনার মেট্রিকের দিকের ত্রুটিযুক্ত পরিমাণের ত্রুটির উপর নির্ভর করে; বা আরও সাধারণভাবে অনুমান তত্ত্ব, ব্যয় কার্যকারিতার সংজ্ঞা।

^ এমএমএসই / এমএমএই ন্যূনতম গড় স্কোয়ার / পরম ত্রুটির সাথে সম্পর্কিত।

ackb বলেছিল "औसत কোণ phi_avg এর সমষ্টি হওয়া উচিত যা সমষ্টি_ phi_avg-phi_i | ^ 2 ন্যূনতম হয় ... তারা কিছু গড় করে তবে কোণ নয়"

---- আপনি গড় বর্গক্ষেত্র অর্থে ত্রুটিগুলির পরিমাণ নির্ধারণ করেন এবং এটি একমাত্র উপায় নয়, তবে এটি বেশিরভাগ সাধারণ উপায়। উত্তরটি এখানে বেশিরভাগ লোকেরা পছন্দ করে (যেমন, ইউনিট ভেক্টরগুলির যোগফল এবং ফলাফলটির কোণটি পাওয়া যায়) আসলে যুক্তিযুক্ত সমাধানগুলির মধ্যে একটি। যদি ভেক্টরদের দিকনির্দেশনা ভন মাইজেস বিতরণ হিসাবে মডেল করা হয় তবে এটি এমএল অনুমানকারী যা আমরা চাই "গড়" দিক হিসাবে কাজ করি। এই বিতরণটি অভিনব নয়, এবং এটি 2 ডি গুয়াসিয়ান থেকে পর্যায়ক্রমে নমুনাযুক্ত বিতরণ। একন দেখুন। (২.১17৯) বিশপের বই "প্যাটার্ন রিকগনিশন এবং মেশিন লার্নিং" তে। আবার, কোনও উপায়েই এটি "গড়" দিকনির্দেশের পক্ষে একমাত্র সেরা, তবে এটি যথেষ্ট যুক্তিসঙ্গত যেটিতে ভাল তাত্ত্বিক সমর্থনযোগ্যতা এবং সহজ বাস্তবায়ন উভয়ই রয়েছে।

নিম্বল বলেছিলেন "এসিবিবি ঠিক আছে যে এই ভেক্টর ভিত্তিক সমাধানগুলিকে সত্যিকারের গড় হিসাবে বিবেচনা করা যায় না, এগুলি কেবলমাত্র ইউনিট ভেক্টর অংশের একটি গড়"

---- এটি সত্য নয়। "ইউনিট ভেক্টর অংশগুলি" কোনও ভেক্টরের দিকনির্দেশনার তথ্য প্রকাশ করে। কোণটি ভেক্টরের দৈর্ঘ্য বিবেচনা না করেই একটি পরিমাণ, এবং ইউনিট ভেক্টর অতিরিক্ত তথ্য সহ এমন দৈর্ঘ্য 1 You


1

চলমান গড় ব্যবহার করে এবং মানগুলিকে স্বাভাবিক করার জন্য যত্ন নেওয়া এখানে একটি সম্পূর্ণ গাণিতিক সমাধান। এটি দ্রুত এবং সঠিক উত্তরগুলি সরবরাহ করে যদি সমস্ত কোণ বৃত্তের একপাশে থাকে (একে অপরের 180 within এর মধ্যে)।

এটি ম্যাথিকভাবে অফসেট যুক্ত করার সমতুল্য যা মানগুলি পরিসীমা (0, 180) এ স্থানান্তর করে, গড়কে গণনা করে এবং পরে অফসেটটি বিয়োগ করে।

মন্তব্যগুলিতে বর্ণনা করা হয় যে কোনও নির্দিষ্ট সময়ে কোন নির্দিষ্ট মানটি নিতে পারে

// angles have to be in the range [0, 360) and within 180° of each other.
// n >= 1
// returns the circular average of the angles int the range [0, 360).
double meanAngle(double* angles, int n)
{
    double average = angles[0];
    for (int i = 1; i<n; i++)
    {
        // average: (0, 360)
        double diff = angles[i]-average;
        // diff: (-540, 540)

        if (diff < -180)
            diff += 360;
        else if (diff >= 180)
            diff -= 360;
        // diff: (-180, 180)

        average += diff/(i+1);
        // average: (-180, 540)

        if (average < 0)
            average += 360;
        else if (average >= 360)
            average -= 360;
        // average: (0, 360)
    }
    return average;
}

1

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

সম্পাদনা: প্রকৃতপক্ষে আমি বুঝতে পেরেছিলাম যে আমার কথোপকথনটি আরও সরল করা যেতে পারে, প্রকৃতপক্ষে উদ্বেগজনকভাবে সমস্ত কথোপকথন এবং অন্যান্য উত্তরে যে ত্রিকোনমিতি চলছে তা বিবেচনা করে simple

/**
 * The Mitsuta method
 *
 * @param angles Angles from 0 - 360
 * @return double array containing
 * 0 - mean
 * 1 - sd: a measure of angular dispersion, in the range [0..360], similar to standard deviation.
 * Note if sd == 90 then the mean can also be its inverse, i.e. 360 == 0, 300 == 60.
 */
public static double[] getAngleStatsMitsuta(double... angles) {
    double sum = 0;
    double sumsq = 0;
    for (double angle : angles) {
        if (angle >= 180) {
            angle -= 360;
        }
        sum += angle;
        sumsq += angle * angle;
    }

    double mean = sum / angles.length;
    return new double[]{mean <= 0 ? 360 + mean: mean, Math.sqrt(sumsq / angles.length - (mean * mean))};
}

... এবং আপনার (জাভা) সমস্ত গিগের জন্য, আপনি উপরের পদ্ধতির সাহায্যে এক লাইনে গড় কোণ পেতে পারেন।

Arrays.stream(angles).map(angle -> angle<180 ? angle: (angle-360)).sum() / angles.length;

আমি বিশ্বাস করি আপনি মিতসুদা পদ্ধতিতে কোনও কিছু মিস করেছেন। দয়া করে উত্তর দিন দ্বারা Lior Kogan পোস্ট কটাক্ষপাত করা stackoverflow.com/a/1828222/9265852
kykzk46

0

আলনিটকের সঠিক সমাধান রয়েছে। নিক ফোর্টেস্কির সমাধান কার্যত একই রকম।

যেখানে বিশেষ ক্ষেত্রে

(যোগফল (x_comp घटक) = 0.0 && যোগফল (y_comp घटक) = 0.0) // উদাহরণস্বরূপ 10 এবং 190 এর 2 টি কোণ degrees ডিগ্রি ইএ।

যোগফল হিসাবে 0.0 ডিগ্রি ব্যবহার করুন

গণনামূলকভাবে আপনাকে এই কেসটির জন্য পরীক্ষা করতে হবে যেহেতু আতান 2 (0।, 0.) অপরিজ্ঞাত এবং এটি একটি ত্রুটি তৈরি করবে।


glibc 'atan2' এর জন্য সংজ্ঞা দেওয়া হয়েছে (0, 0) - ফলাফল 0
Alnitak

0

গড় কোণ phi_avg এর সমষ্টি হওয়া উচিত যা সমষ্টি_ ph | সমস্ত ইনপুট মানকে [0, 2Pi) এ স্বাভাবিক চালিয়ে, চলমান গড় phi_run রেখে এবং সাধারণীকরণ চয়ন করে এটি সহজেই অর্জন করা যায় | phi_i-phi_run | [-পি, পাই) এ (2 পিআই যোগ বা বিয়োগ করে) উপরের বেশিরভাগ প্রস্তাবনাগুলি এমন অন্য কিছু করে যাতে তার ন্যূনতম সম্পত্তি না থাকে, অর্থাত্ তারা কিছু গড় দেয় তবে কোণ নয়।


0

আমি @ ডেভিড_হানাকের উত্তরের সাহায্যে সমস্যাটি সমাধান করেছি। যেমন তিনি বলেছেন:

একই অর্ধবৃত্তে অবস্থান করার সময় যে কোণটি দু'জনের মধ্যে "নির্দেশ করে, যেমন 355 এবং 5 এর জন্য এটি 0 হবে 180 হবে না this এটি করার জন্য আপনাকে দুটি কোণগুলির মধ্যে পার্থক্য 180 এর চেয়ে বড় কিনা তা পরীক্ষা করে দেখতে হবে অথবা না. যদি তা হয় তবে উপরের সূত্রটি ব্যবহারের আগে 360 দ্বারা ছোট কোণটি বৃদ্ধি করুন।

সুতরাং আমি যা করেছি তা সমস্ত কোণগুলির গড় গণনা করা হয়েছিল। এবং তারপরে সমস্ত কোণগুলি এর চেয়ে কম, এগুলি 360 কে বাড়িয়ে দিন Then

        float angleY = 0f;
        int count = eulerAngles.Count;

        for (byte i = 0; i < count; i++)
            angleY += eulerAngles[i].y;

        float averageAngle = angleY / count;

        angleY = 0f;
        for (byte i = 0; i < count; i++)
        {
            float angle = eulerAngles[i].y;
            if (angle < averageAngle)
                angle += 360f;
            angleY += angle;
        }

        angleY = angleY / count;

পুরোপুরি কাজ করে।


0

পাইথন ফাংশন:

from math import sin,cos,atan2,pi
import numpy as np
def meanangle(angles,weights=0,setting='degrees'):
    '''computes the mean angle'''
    if weights==0:
         weights=np.ones(len(angles))
    sumsin=0
    sumcos=0
    if setting=='degrees':
        angles=np.array(angles)*pi/180
    for i in range(len(angles)):
        sumsin+=weights[i]/sum(weights)*sin(angles[i])
        sumcos+=weights[i]/sum(weights)*cos(angles[i])
    average=atan2(sumsin,sumcos)
    if setting=='degrees':
        average=average*180/pi
    return average

0

আপনি মতলব এ এই ফাংশনটি ব্যবহার করতে পারেন:

function retVal=DegreeAngleMean(x) 

len=length(x);

sum1=0; 
sum2=0; 

count1=0;
count2=0; 

for i=1:len 
   if x(i)<180 
       sum1=sum1+x(i); 
       count1=count1+1; 
   else 
       sum2=sum2+x(i); 
       count2=count2+1; 
   end 
end 

if (count1>0) 
     k1=sum1/count1; 
end 

if (count2>0) 
     k2=sum2/count2; 
end 

if count1>0 && count2>0 
   if(k2-k1 >= 180) 
       retVal = ((sum1+sum2)-count2*360)/len; 
   else 
       retVal = (sum1+sum2)/len; 
   end 
elseif count1>0 
    retVal = k1; 
else 
    retVal = k2; 
end 

অ্যালগরিদমটি কেবলমাত্র কাজ করে দেখা যাচ্ছে তবে বাস্তবে এটি বাস্তব বিশ্বে খারাপভাবে ব্যর্থ হতে পারে। আপনাকে প্রদত্ত কোণগুলির বিপরীত দিকের কোণ মানের iving
তোথফু

0

যে কোনও প্রোগ্রামিং ভাষার জন্য আপনি নীচের লিঙ্কটিতে একটি সমাধান এবং সামান্য ব্যাখ্যা দেখতে পাচ্ছেন: https://rosettacode.org/wiki/A સરેરાશ/Mean_angle

উদাহরণস্বরূপ, সি ++ সমাধান :

#include<math.h>
#include<stdio.h>

double
meanAngle (double *angles, int size)
{
  double y_part = 0, x_part = 0;
  int i;

  for (i = 0; i < size; i++)
    {
      x_part += cos (angles[i] * M_PI / 180);
      y_part += sin (angles[i] * M_PI / 180);
    }

  return atan2 (y_part / size, x_part / size) * 180 / M_PI;
}

int
main ()
{
  double angleSet1[] = { 350, 10 };
  double angleSet2[] = { 90, 180, 270, 360};
  double angleSet3[] = { 10, 20, 30};

  printf ("\nMean Angle for 1st set : %lf degrees", meanAngle (angleSet1, 2));
  printf ("\nMean Angle for 2nd set : %lf degrees", meanAngle (angleSet2, 4));
  printf ("\nMean Angle for 3rd set : %lf degrees\n", meanAngle (angleSet3, 3));
  return 0;
}

আউটপুট:

Mean Angle for 1st set : -0.000000 degrees
Mean Angle for 2nd set : -90.000000 degrees
Mean Angle for 3rd set : 20.000000 degrees

বা মতলব সমাধান :

function u = mean_angle(phi)
    u = angle(mean(exp(i*pi*phi/180)))*180/pi;
end

 mean_angle([350, 10])
ans = -2.7452e-14
 mean_angle([90, 180, 270, 360])
ans = -90
 mean_angle([10, 20, 30])
ans =  20.000

0

স্টারব্লিউয়ের উত্তরটি গড় একক ভেক্টরের কোণ দেয়, তবে আপনি যদি গ্রহণ করেন যে 0 থেকে 2 * পাই (বা 0 ° থেকে 0 এর মধ্যে) একাধিক উত্তর থাকতে পারে তবে স্বীকৃত কোণগুলিতে গাণিতিক গড় ধারণাটি প্রসারিত করা সম্ভব 360 °)। উদাহরণস্বরূপ, গড়ে 0 ° এবং 180 either হয় 90 ° বা 270 ° হতে পারে °

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

এই ধারণাটি যে কোনও মাত্রাতে প্রসারিত হতে পারে, যেহেতু ইউনিট গোলকের বরাবর দূরত্বটি ইউনিট বৃত্তের সাথে দূরত্বের সাথে ঠিক একইভাবে গণনা করা যায় - দুটি ইউনিট ভেক্টরের ডট প্রোডাক্টের বিপরীত কোসাইন।

চেনাশোনাগুলির জন্য আমরা বেশ কয়েকটি উপায়ে এই গড়ের জন্য সমাধান করতে পারতাম, তবে আমি নিম্নলিখিত ও (এন ^ 2) অ্যালগরিদমকে প্রস্তাব করি (কোণগুলি রেডিয়ানগুলিতে থাকে এবং আমি ইউনিট ভেক্টর গণনা এড়াতে পারি):

var bestAverage = -1
double minimumSquareDistance
for each a1 in input
    var sumA = 0;
    for each a2 in input
        var a = (a2 - a1) mod (2*pi) + a1
        sumA += a
    end for
    var averageHere = sumA / input.count
    var sumSqDistHere = 0
    for each a2 in input
        var dist = (a2 - averageHere + pi) mod (2*pi) - pi // keep within range of -pi to pi
        sumSqDistHere += dist * dist
    end for
    if (bestAverage < 0 OR sumSqDistHere < minimumSquareDistance) // for exceptional cases, sumSqDistHere may be equal to minimumSquareDistance at least once. In these cases we will only find one of the averages
        minimumSquareDistance = sumSqDistHere
        bestAverage = averageHere
    end if
end for
return bestAverage

যদি সমস্ত কোণ একে অপরের 180 within এর মধ্যে থাকে তবে আমরা একটি সহজ হে (এন) + ও (সাজান) অ্যালগরিদম (আবার রেডিয়ান ব্যবহার করে এবং ইউনিট ভেক্টরের ব্যবহার এড়ানো) ব্যবহার করতে পারি:

sort(input)
var largestGapEnd = input[0]
var largestGapSize = (input[0] - input[input.count-1]) mod (2*pi)
for (int i = 1; i < input.count; ++i)
    var gapSize = (input[i] - input[i - 1]) mod (2*pi)
    if (largestGapEnd < 0 OR gapSize > largestGapSize)
        largestGapSize = gapSize
        largestGapEnd = input[i]
    end if
end for
double sum = 0
for each angle in input
    var a2 = (angle - largestGapEnd) mod (2*pi) + largestGapEnd
    sum += a2
end for
return sum / input.count

ডিগ্রি ব্যবহার করতে, কেবল পিআই প্রতিস্থাপন করুন 180 দিয়ে you


0

সমস্যা অত্যন্ত সহজ। 1. সমস্ত কোণ -180 এবং 180 ডিগ্রির মধ্যে রয়েছে তা নিশ্চিত করুন। ২. একটি সমস্ত অ-নেতিবাচক কোণ যুক্ত করুন, তাদের গড় নিন এবং কতগুলি ২. বি.সকল নেতিবাচক কোণ যুক্ত করুন, তাদের গড় এবং কতটি COUNT রাখবেন। ৩. পোস্ট_ভরেজ বিয়োগের পার্থক্য নিন নেগ_ভেরেজ পার্থক্য যদি 180 এর চেয়ে বেশি হয় তবে পার্থক্যটি 360 বিয়োগের পার্থক্যে পরিবর্তন করুন। অন্যথায় কেবল পার্থক্যের চিহ্নটি পরিবর্তন করুন। নোট করুন যে পার্থক্য সর্বদা অ-নেতিবাচক থাকে। গড়_অঙ্গেলটি পোষ্ট_ভ্যারিজ সমান পার্থক্যের "ওজন" সমান, নেতিবাচক এবং ধনাত্মক গণনার যোগফলকে বিভাজিত


0

গড় কোণগুলির জন্য এখানে কিছু জাভা কোড রয়েছে, আমি মনে করি এটি যুক্তিসঙ্গতভাবে শক্ত।

public static double getAverageAngle(List<Double> angles)
{
    // r = right (0 to 180 degrees)

    // l = left (180 to 360 degrees)

    double rTotal = 0;
    double lTotal = 0;
    double rCtr = 0;
    double lCtr = 0;

    for (Double angle : angles)
    {
        double norm = normalize(angle);
        if (norm >= 180)
        {
            lTotal += norm;
            lCtr++;
        } else
        {
            rTotal += norm;
            rCtr++;
        }
    }

    double rAvg = rTotal / Math.max(rCtr, 1.0);
    double lAvg = lTotal / Math.max(lCtr, 1.0);

    if (rAvg > lAvg + 180)
    {
        lAvg += 360;
    }
    if (lAvg > rAvg + 180)
    {
        rAvg += 360;
    }

    double rPortion = rAvg * (rCtr / (rCtr + lCtr));
    double lPortion = lAvg * (lCtr / (lCtr + rCtr));
    return normalize(rPortion + lPortion);
}

public static double normalize(double angle)
{
    double result = angle;
    if (angle >= 360)
    {
        result = angle % 360;
    }
    if (angle < 0)
    {
        result = 360 + (angle % 360);
    }
    return result;
}

-3

আমার কাছে @ স্টারব্লু থেকে আলাদা পদ্ধতি রয়েছে যা উপরের কয়েকটি কোণকে "সঠিক" উত্তর দেয়। উদাহরণ স্বরূপ:

  • angle_avg ([350,10]) = 0
  • angle_avg ([- 90,90,40]) = 13,333
  • angle_avg ([350,2]) = 356

এটি একটানা কোণগুলির মধ্যে পার্থক্যগুলির উপরে একটি যোগফল ব্যবহার করে। কোড (মতলব মধ্যে):

function [avg] = angle_avg(angles)
last = angles(1);
sum = angles(1);
for i=2:length(angles)
    diff = mod(angles(i)-angles(i-1)+ 180,360)-180
    last = last + diff;
    sum = sum + last;
end
avg = mod(sum/length(angles), 360);
end

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