কেন Computer Science-এ গণিত লাগে
Why Mathematics for Computer Science
গণিতের কোন অংশটা CS-এ আসলেই কাজে লাগে, কোনটা লাগে না — আর কেন এই কারিকুলাম logic দিয়ে শুরু হয়, calculus দিয়ে নয়।
আগে এটা বুঝি
আপনি হয়তো ইতিমধ্যে কোড লিখতে পারেন। হয়তো ভালোই পারেন। তাহলে প্রশ্ন হলো — গণিত দিয়ে শুরু করছি কেন?
উত্তরটা সোজা: প্রোগ্রামিং হলো গণিত লেখার একটা উপায়, যেটা চলে।
একটা if statement হলো propositional logic। একটা for loop-এর correctness
প্রমাণ করতে লাগে induction। একটা hash table কেন কাজ করে সেটা probability।
একটা network কেন partition হয় সেটা graph theory। একটা algorithm “দ্রুত”
কি না সেটা asymptotic analysis।
এগুলো না জানলেও কোড লেখা যায় — কিন্তু তখন আপনি জানেন কী করতে হয়, জানেন না কেন কাজ করে। আর যেদিন কাজ করবে না, সেদিন আটকে যাবেন।
মূল ধারণা
CS-এর গণিত অন্যরকম
স্কুল-কলেজে গণিত মানে ছিল মূলত continuous mathematics — calculus, limits, integration। ধারাবাহিক, মসৃণ জিনিস মাপার গণিত।
Computer Science-এর মূল গণিত discrete mathematics — আলাদা আলাদা, গোনা যায় এমন জিনিসের গণিত। কারণটা hardware-এ:
- Transistorহয় on, নয় off — মাঝামাঝি কিছু নেই
- Bit0 অথবা 1
- Byte২৫৬টি সম্ভাব্য মান — গোনা যায়
- Memoryসীমিত সংখ্যক address
- Program stateসীমিত, discrete অবস্থার সেট
- Computationএক state থেকে আরেক state — লাফিয়ে, মসৃণভাবে নয়
Computer-এ কোনো কিছুই “একটু একটু করে” বদলায় না। সব লাফ দিয়ে বদলায়। তাই যে গণিত দিয়ে computer বোঝা যায়, সেটাও লাফের গণিত।
ভেতরে কী ঘটছে
এই মডিউলে কী কী আছে, আর কেন
প্রতিটা topic এখানে আছে একটা নির্দিষ্ট কারণে — CS-এর কোথাও না কোথাও এটা সরাসরি লাগবে।
| গণিতের অংশ | CS-এ কোথায় লাগে |
|---|---|
| Propositional logic | if/while condition, circuit design, SQL WHERE |
| Predicate logic | Database query, formal specification, type system |
| Sets | Data structure, relational algebra, type theory |
| Relations & functions | Database schema, mapping, hash function |
| Proof techniques | Algorithm correctness, security argument |
| Induction | Recursion, loop invariant, tree algorithm |
| Combinatorics | Complexity counting, hash collision, password space |
| Probability | Hash table, randomized algorithm, ML, network reliability |
| Graph theory | Network, dependency, compiler CFG, social graph |
| Boolean algebra | Digital logic, circuit simplification |
| Number systems | Binary, hex, modular arithmetic, cryptography |
| Linear algebra | Graphics, ML, PageRank, signal processing |
| Asymptotic notation | সব algorithm-এর cost ভাষা |
উদাহরণ
একটা উদাহরণ: loop কেন কাজ করে
এই কোডটা দেখুন:
int sum(int n) {
int s = 0;
for (int i = 1; i <= n; i++) {
s += i;
}
return s;
}প্রশ্ন: এটা কি সব n ≥ 0-এর জন্য n(n+1)/2 রিটার্ন করে?
“চালিয়ে দেখলাম, ঠিক আছে” — এটা প্রমাণ না। আপনি সব n চালাতে পারবেন না।
প্রমাণটা লাগে loop invariant দিয়ে, আর invariant প্রমাণ হয় induction দিয়ে:
Invariant: প্রতিবার loop body শেষ হওয়ার পর,
s= 1 থেকেiপর্যন্ত সব সংখ্যার যোগফল।
- Base: প্রথম iteration-এর আগে
s = 0, যেটা খালি যোগফল। ✓ - Step: ধরুন
k-তম iteration-এর পর invariant সত্য, অর্থাৎs = 1+2+…+k। পরের iteration-এi = k+1হয়েs += (k+1)হবে, তাইs = 1+2+…+k+(k+1)। ✓ - Termination: Loop থামে যখন
i = n+1, তখনs = 1+2+…+n = n(n+1)/2। ∎
এই যুক্তিটা আপনি n = 5 টেস্ট করে পেতেন না। এটা সব n-এর জন্য সত্য।
নিজে চালিয়ে দেখুন
Discrete-এর সীমা নিজে দেখুন
Python খুলে এই তিনটা লাইন চালান:
>>> 0.1 + 0.2
0.30000000000000004
>>> 0.1 + 0.2 == 0.3
False
>>> import sys; sys.float_info.epsilon
2.220446049250313e-16গণিতে 0.1 + 0.2 ঠিক 0.3। Computer-এ না।
কারণ: 0.1 কে binary-তে ঠিকভাবে লেখা যায় না — ঠিক যেমন 1/3 কে
decimal-এ ঠিকভাবে লেখা যায় না (0.3333… অসীম)। Computer-এর কাছে
সীমিত সংখ্যক bit আছে, তাই সে কাছাকাছি একটা মান রাখে।
এবার এটা চালান:
>>> 2**1000
# ১০০০ bit-এর বিশাল সংখ্যা — Python-এ কাজ করে
>>> import numpy as np
>>> np.int64(2)**63
# OverflowError বা negative — কারণ 64 bit-এ আঁটে নাComputer-এর সংখ্যা অসীম নয়, আর float 'বাস্তব সংখ্যা' নয় — এটা discrete approximation. Level 1-এ আমরা ঠিক কেন সেটা দেখব।
বাস্তব সিস্টেমে
বাস্তবে এটা কোথায় কামড়ায়
- 1996, Ariane 5 rocket — ৬৪-bit float কে ১৬-bit integer-এ রূপান্তরের সময় overflow। রকেট উৎক্ষেপণের ৩৭ সেকেন্ড পর ধ্বংস। ক্ষতি ~$৩৭০ মিলিয়ন।
- Boeing 787 — একটা counter ২৪৮ দিন পর overflow করত, যা সব generator control unit একসাথে বন্ধ করে দিতে পারত। FAA-কে জরুরি নির্দেশ দিতে হয়েছিল: প্রতি ২৪৮ দিনে reboot।
- Binary search-এর bug — Jon Bentley-র বইয়ে ২০ বছর ধরে ছিল, Java-র standard library-তেও ছিল:
(low + high) / 2বড় array-তে overflow করে। ঠিক করা হয়েছেlow + (high - low) / 2দিয়ে।
এই তিনটাই গণিতের ভুল না — এগুলো computer-এ গণিত কীভাবে কাজ করে সেটা না জানার ভুল।
যে ভুলগুলো সবাই করে
“ভালো programmer হতে হলে গণিতে ভালো হতে হয়।”
সত্যি না — অন্তত সাধারণ অর্থে না। আপনার calculus-এ ভালো হওয়ার দরকার নেই, integration মুখস্থ থাকার দরকার নেই। যেটা দরকার সেটা হলো যুক্তিবদ্ধভাবে চিন্তা করার অভ্যাস: একটা দাবি সত্য কি না সেটা যাচাই করা, edge case খুঁজে বের করা, “সব ক্ষেত্রে” আর “যেসব ক্ষেত্রে টেস্ট করলাম” -এর পার্থক্য বোঝা।
“এই গণিতগুলো interview-এর জন্য, বাস্তব কাজে লাগে না।”
বাস্তব কাজে লাগে, কিন্তু ছদ্মবেশে। আপনি যখন সিদ্ধান্ত নেন “এই cache-এ কত বড় hash table লাগবে” — সেটা probability। “এই microservice graph-এ circular dependency আছে কি না” — সেটা topological sort। “এই retry logic কি সব ক্ষেত্রে থামবে” — সেটা termination proof।
“AI থাকতে গণিত শেখার দরকার কী।”
AI আপনাকে কোড দিতে পারে। কিন্তু সেই কোড ঠিক কি না, edge case-এ ভাঙবে কি না, complexity গ্রহণযোগ্য কি না — সেটা যাচাই করার দায়িত্ব আপনার। যাচাই করার ক্ষমতা মানেই এই গণিত।
বুঝেছেন কি না দেখুন
1কেন CS-এ discrete mathematics-এর গুরুত্ব continuous mathematics-এর চেয়ে বেশি?
যুক্তি
কারণ computer-এর প্রতিটা স্তরই discrete। Transistor on/off, memory-তে সীমিত সংখ্যক address, program-এর সীমিত সংখ্যক state। Computation মানে এক discrete state থেকে আরেক discrete state-এ যাওয়া। তাই যে গণিত এই লাফানো, গোনা-যায় এমন জিনিস নিয়ে কাজ করে — সেটাই মানানসই।
Continuous mathematics দরকার হয় যখন আমরা discrete জিনিস দিয়ে continuous কিছু approximate করি (যেমন float দিয়ে বাস্তব সংখ্যা, বা ML-এ gradient)।
2একটা function ১০০০টা random input-এ ঠিক উত্তর দিল। এটা কি প্রমাণ করে
function-টা correct? না হলে, কী প্রমাণ করে?
প্রয়োগ
না। ১০০০টা input মানে ১০০০টা ক্ষেত্রে ঠিক — কিন্তু input space সাধারণত
অনেক বড় (একটা int32 parameter-এই ৪৩০ কোটি সম্ভাবনা)।
Testing প্রমাণ করে ভুল আছে (একটা failing test যথেষ্ট)। Testing প্রমাণ করতে পারে না ভুল নেই। Correctness প্রমাণ করতে লাগে formal argument — loop invariant, induction, বা exhaustive case analysis।
Dijkstra-র বিখ্যাত কথাটা এখানে: “Program testing can be used to show the presence of bugs, but never to show their absence.”
30.1 + 0.2 != 0.3 — এটা কি Python-এর bug? উত্তর ব্যাখ্যা করুন।
যুক্তি
0.1 + 0.2 != 0.3 — এটা কি Python-এর bug? উত্তর ব্যাখ্যা করুন।না, এটা bug না — এটা IEEE 754 floating-point standard-এর নির্ধারিত আচরণ, আর প্রায় সব ভাষাতেই একই ঘটে (C, Java, JavaScript, Rust)।
কারণ: 0.1 দশমিকে সুন্দর, কিন্তু binary-তে এটা একটা অসীম পুনরাবৃত্ত ভগ্নাংশ
(0.0001100110011…)। ৬৪ bit-এ সেটা কেটে রাখতে হয়, তাই সামান্য ত্রুটি থাকে।
দুইটা approximate সংখ্যা যোগ করলে ত্রুটিও যোগ হয়।
Level 1-এ আমরা bit ধরে ধরে দেখব ঠিক কোথায় ত্রুটিটা ঢোকে।
এরপর কী
এরপরের লেসনে আমরা শুরু করব propositional logic দিয়ে — কারণ এটাই
সবচেয়ে নিচের স্তর। if (a && !b) থেকে শুরু করে CPU-র ভেতরের AND gate,
সবই একই logic-এর ভিন্ন রূপ।
আর সেই logic যখন আমরা Level 2-তে transistor দিয়ে বানাব, তখন এই লেসনের কথাটা মনে পড়বে: গণিতটা আলাদা কিছু না, hardware-টাই গণিতের ভৌত রূপ।
আরও পড়ুন
- Mathematics for Computer Science — Lehman, Leighton, Meyer (MIT 6.042) · এই মডিউলের মেরুদণ্ড