Showing posts with label নাম্বার থিওরী. Show all posts
Showing posts with label নাম্বার থিওরী. Show all posts

Fast Doubling method to find nth Fibonacci number

Before Fast Doubling Method, lets discuss some naïve method to find nth fibonacci number.
Fibonacci Table

1. Recursive Method :
Recursive method is quite known approach to count fibonacci number but its very slow.
Here is the formula to find nth fibonacci number ,
F(0) = 0;
F(1) = 1;
F(n) = F(n-1) + F(n-2) ;
As an example n = 6;
using this above table , F(n) = 5+3 = 8;
// Here is the sample program ,
Its complexity is O(2^n).



2. Iterative method :
This method is too popular but its also very slow to count large fibonacci number. Its use the same formula I have discussed avobe.
// Here is the sample program.
Its complexity O(n). 



3. Fast Doubling Method :
This is the faster method than the above two method. We have few methods to calculate fibonacci number in faster way. Out of them  matrix exponentiation is most commonly used concept. Another well known concept is fast doubling method. It is called fast doubling method because every time you will found the twice fibonacci number for each n.
Fast doubling is based on two formula.
F(2n) = F(n)[2*F(n+1) – F(n)]
F(2n + 1) = F(n)2 + F(n+1)2
Lets see an example, n = 4;
F(2*4) = F(4) [ 2*F(5) – F(4)]; // follow the above table
=> F(8) = F(4) [ 2*5 – 3];
=> F(8) = 3 * 7;
=> F(8) = 21; // Here we get the F(8) nth fibonacci number.
The 2nd equation is as same as it.
F(9) = F(4)2 +F(5)2  ;
=> F(9) = 32 +52 ;
=> F(9) = 34 ;
// Here is the program.
This code has a complexity of O(log n) which is way too faster than previously discussed function.



Please don't feel shy to comment to improve these program and if you have better program please let me know. 

Fermat’s theorem -- (ফারমাট'স থেওরেম)

An Integer can be represented as the sum of two square number.

অর্থাৎ একটি integer সংখ্যাকে দুটি সংখ্যার বর্গের যোগফল হিসেবে প্রকাশ করা যায়।এটি একটি classical Math প্রবলেম। এটিকে আমরা এভাবে লিখতে পারি x = a2+b2

Fermat’s theorem এর সাহায্যে খুব সহজেই এটা বের করা যায়।

একটি সংখ্যা x কে দুটি পূর্ণ সংখ্যার বর্গের যোগফল হিসেবে প্রকাশ করা যাবে যদি ওই সংখ্যাটির (x) প্রাইম factorization এর প্রতিটি প্রাইম ফ্যাক্টর 4k+3 ফর্মে থাকে জোড় সংখ্যক বার।

যেমনঃ 147 এর প্রাইম factorization করলে এর প্রাইম ফ্যাক্টর গুলো পাওয়া যাবে 3,7,7
3 কে 4k+3 ফর্মে প্রকাশ করা যায় না।  

7 কে 4k+3 ফর্মে প্রকাশ করা যায় যেখানে k=1 (k>=1)। এবং 7 আছে দুই বার। তাই 147 কে দুটি সংখ্যার বর্গের যোগফল হিসেবে প্রকাশ করা যায়।

আর একটা উদাহরণ দেখা যাক,

42 = 2*3*7  এই প্রাইম ফ্যাক্টর গুলোর মধ্যে মাত্র 7 কে 4k+3 ফর্মে প্রকাশ করা যায়, 2 এবং 3 কে যায় না। তাই 47 কে কখনোই দুটি সংখ্যার বর্গের যোগফল হিসেবে প্রকাশ করা যাবে না।


Fermat’s Theorem :  কোন প্রাইম নাম্বারকে দুটি সংখ্যার বর্গের যোগফল হিসেবে প্রকাশ করা যাবে শুধুমাত্র যদি ওই প্রাইম নাম্বারকে 4 দিয়ে ভাগ করলে ভাগশেষ 1 থাকে (p = 1 (mod 4) ।(অথবা p কে যদি 4k+1 ফর্মে লেখা যায় তাহলেই একে p = a2 + b2  ফর্মে লেখা যাবে ) 

উইলসন থিওরেম

প্রাইম নাম্বার বের করার জন্য সিভের অ্যালগরিদম প্রায় সবাই জানে, অনেকের অ্যালগোরিদম শেখার শুরুটাও এই সিভ দিয়ে আমার নিজের তাই। যাই হোক প্রাইম নাম্বার চেক করার জন্য আর একটি সহজ থিওরি হচ্ছে এই উইসন থিওরেম।
উইলসন থিওরেমকে এভাবে বলা যায়, একটি natural number  n( n>1 )প্রাইম হবে যদি (( n-1)!) mod n =n-1 হয়।
এটাই হচ্ছে উইলসন থিওরেম
(n-1) ! = 1*2*3*4*5*……………………*n-1 ;

একটা উদাহরণ দেওয়া যাক,

ধরা যাক n=6

(n-1)! mod n = 5! Mod 6 = 0
0 is not equal to n-1 = 5 , So n=6  is not prime .

Another Example :

Assume, n=7
(n-1)! mod n = 6! Mod 7 = 6
6 is equal to n-1 = 6 , So n=7  is prime .



এভাবে একে implement করা যায়,





একটা বিষয় মাথায় রাখতে হবে অনেক বড় সংখ্যার প্রোগ্রামটি ক্ষেত্রে একটু slow কাজ করতে পারে সেক্ষেত্রে আবার mod m অর্থাৎ fact=((fact*i) %m)%m;  করতে হবে।  

উইলসন থিওরেম এর প্রমাণ এই লিঙ্কে  সুন্দর ভাবে দেওয়া আছে,কষ্ট করে দেখে নিবেন।


তবে আমি একটু অন্যভাবে এইটা প্রমাণ করার চেষ্টা করছি, সেটা হচ্ছে সিভের অ্যালগোরিদম দিয়ে 1 থেকে 10000000 পর্যন্ত প্রাইম নাম্বার বের করি এবং একটা prime.txt ফাইলে সেভ করি তারপর উইলসন দিয়ে চেক করি প্রাইম নাকি প্রাইম নয় এবং primeCheck.txt ফাইলে সেভ করি, এরকম ভাবে,  


একটা output দেখা যাক 10000000 পর্যন্ত ঠিকঠাক কাজ করতেছে। 


আপনারা চাইলে এখান থেকে পোস্টটি txt ফাইল সহ  PDF Download করে নিতে পারেন।
লেখাটা বাংলিশ হয়ে গেল আশা করি ক্ষমা সুন্দর দৃষ্টিতে দেখবেন।

** আমার কোথাও ভুল হতে পারে,দয়া করে মন্তব্য করবেন।ভুল করার প্রবনতাই মানুষকে অন্যান্য সৃষ্টি থেকে আলাদা করে। 


Divisors কথন !!

খুব সাধারন একটা প্রোগ্রামিং প্রবলেম- n একটি integer এর Total Divisor সংখ্যা বের করতে হবে, সহজ কথায় যে সকল সংখ্যা দিয়ে n কে ভাগ করলে ভাগফল শূন্য থাকে সে সকল সংখ্যাই হচ্ছে n এর divisor
এখন 1 থেকে n-1  পর্যন্ত লুপ চালালেই আমরা বের করতে পারবো n এর  divisor গুলো।

for(i=1;i<n;i++){
if(n%i==0)
printf(“Divisor : %d ”,i);
}

সহজ হিসাব কিন্তু n এর value যদি অনেক বড় হয় ধরা যাক n=1000000 তাহলে কি হবে  আমার লুপ চলবে 999999 পর্যন্ত, তার মানে প্রোগ্রামের Run Time অনেক বেড়ে যাবে

কিন্তু আমরা যদি চাই তাহলে প্রোগ্রামটি আরও efficient করতে পারি।

n এর divisor বের করার জন্য n-1 পর্যন্ত ভাগ করে দেখার প্রয়োজন নাই আমরা n/2 পর্যন্ত ভাগ করেই n এর divisors  গুলো বের করতে পারি, n  কে n/2 এর পর আর কোন সংখ্যা দিয়ে ভাগ করা যাবে না, মানে n যদি composite number হয় তাহলে একে 1 থেকে n/2 পর্যন্ত সংখ্যা দিয়েই ভাগ করা যাবে

যেমনঃ

n=10 , n/2=5
থেকে এর মধ্যে সংখ্যা আছে ,,,,৫।তাহলে ১০ এর divisor 2 and 5। 
Total Divisor সংখ্যা = 6  (include 1 and 28)

কিন্তু তারপরও প্রোগ্রাম খুব একটা efficient হয় না, আমি প্রোগ্রামটির execution time বের করে দিয়েছি একটু খেয়াল করে দেখলেই বুঝতে পারবেন।

// code



Prime Factorization এর মাধ্যমে অনেক efficient wayতে কোন নাম্বারের মোট Divisor সংখ্যা বের করা যায়।

কোন natural  নাম্বারকে তার প্রাইম ফ্যাক্টর গুলোর product হিসেবে represent করা যায়

n= xa  * yb  * Z…………….
এখানে n একটি প্রাইম integer number, X,Y and Z হচ্ছে n এর প্রাইম ফ্যাক্টর এবং a,b and c হচ্ছে X,Y,Z এর exponent
এখন n এর Divisor সংখ্যা calculate করা যায় এভাবে,
d=(a+1)*(b+1)*(c+1)*…………………..
একটা উদাহরণ দেওয়া যায় এভাবে,
n=Xa * Yb  
n=2²*71
a=2, b=1
number of divisor = (a+1)*(b+1) = =(2+1)*(1+1 )= 6
অর্থাৎ 28 এর Divisor সংখ্যা 6

আরেক ভাবে আমরা Divisor বের করতে পারি, কোন সংখ্যা n এর Divisor বের করার জন্য আমাদের n/2 পর্যন্ত ভাগ করে দেখার দরকার নাই, ওই সংখ্যার বর্গমূল (sqrt(n)) পর্যন্ত চেক করলেই হবে।

কেননা, যদি n=a×b হয় (অর্থাৎ n যদি যৌগিক সংখ্যা হয়) আর তাদের একটা ডিভিজর যদি sqrt(n) এর ছোট হয়, অন্যটা অবশ্যই sqrt(n) এর বড় হবে সেজন্য sqrt(n) এর ছোট সবক'টা ডিভিজর এর জন্য আমরা divisor কে 1 করে না বাড়িয়ে 2 করে বাড়াতে পারি। শুধু যদি কোন ডিভিজর sqrt(n)  সমান হয় তাহলে 1 যোগ হবে(এটা হয় শুধু মাত্র perfect square number এর ক্ষেত্রে)

যেমনঃ n=28,  sqrt(n)=5

5 এর থেকে ছোট 28 Divisor গুলো হল 1,2,4 যাদের প্রত্যেকটির জন্য আমরা আরেকটি Divisor পাবো যেটি কিনা sqrt(n)=5 এর চেয়ে বড়।

28%1==0 so divisor = 1 and 28
28%2==0 so divisor = 2 and 14
28%4==0 so divisor = 4 and 7
Total = 6 (notice that 28,14 and are greater than 5,that why we should increment our divisor counter +2)

36 (perfect square number)
sqrt(36)=6

36%1==0 so divisor = 1 and 36
36%2==0 so divisor = 2 and 18   
36%3==0 so divisor            = 3 and 12
36%4==0 so divisor = 4 and 9
36%6==0 so divisor = 6 and 36 (notice that 36 is counted previous that why we should increment the step just 1)

Total Divisor = 9




Practice Problem  : uva – 294 , projecteuler- problem-12

Author : Md. Shohanur Rahaman
Date : 01/01/2015
Contact : shohan4556@gmail.com

Download PDF