<jupyter_start><jupyter_text>Deutsch-Jozsa অ্যালগরিদম এই বিভাগে, আমরা প্রথমে Deutsch-Jozsa সমস্যা এবং এটি সমাধান করার জন্য ক্লাসিক্যাল এবং কোয়ান্টাম অ্যালগরিদম উপস্থাপন করি। তারপরে আমরা কিস্কিট ব্যবহার করে কোয়ান্টাম অ্যালগরিদম বাস্তবায়ন করবএবং এটি একটি সিমুলেটর এবং ডিভাইসে চালাবো।  1। পরিচিতি Deutsch-Jozsa অ্যালগরিদম, প্রথম রেফারেন্স [1]-এ প্রবর্তিত হয়েছিল, এটি একটি কোয়ান্টাম অ্যালগরিদমের প্রথম উদাহরণ যা সেরা ক্লাসিক্যাল অ্যালগরিদমের চেয়ে ভাল কাজ করে। এটি দেখিয়েছে যে একটি নির্দিষ্ট সমস্যার জন্য একটি কম্পিউটেশনাল টুল হিসাবে একটি কোয়ান্টাম কম্পিউটার ব্যবহার করার সুবিধা থাকতে পারে।  1.1 ডয়েচ-জোজসা সমস্যা আমাদেরকে একটি লুকানো বুলিয়ান ফাংশন $f$ দেওয়া হয়েছে, যা ইনপুট হিসাবে বিটগুলির একটি স্ট্রিং নেয় এবং $0$ বা $1$ প্রদান করে, অর্থাৎ:$$ f({x_0,x_1,x_2,...}) \rightarrow 0 \textrm{ or } 1 \textrm{ , where } x_n \textrm{ is } 0 \textrm{ or } 1$$প্রদত্ত বুলিয়ান ফাংশনের বৈশিষ্ট্য হল এটি হয় সুষম বা ধ্রুবক হওয়ার নিশ্চয়তা। একটি ধ্রুবক ফাংশন যেকোনো ইনপুটের জন্য সমস্ত $0$'স বা সমস্ত $1$'স ফেরত দেয়, যখন একটি ভারসাম্যপূর্ণ ফাংশন সমস্ত ইনপুটের অর্ধেকের জন্য $0$' এবং বাকি অর্ধেকের জন্য $1$'স ফেরত দেয়। আমাদের কাজ হল প্রদত্ত ফাংশনটি সুষম বা ধ্রুবক কিনা তা নির্ধারণ করা।মনে রাখবেন যে Deutsch-Jozsa সমস্যাটি একক বিট ডয়েচ সমস্যার একটি $n$-বিট এক্সটেনশন। 1.2ক্লাসিক্যাল সমাধান ক্লাসিকভাবে, সর্বোত্তম ক্ষেত্রে, ওরাকলের কাছে দুটি প্রশ্ন নির্ধারণ করতে পারে যে লুকানো বুলিয়ান ফাংশন, $f(x)$, ভারসাম্যপূর্ণ কিনা: যেমন আমরা যদি $f(0,0,0,...)\rightarrow উভয়ই পাই 0$ এবং $f(1,0,0,...) \rightarrow 1$, তাহলে আমরা জানি যে ফাংশনটি ভারসাম্যপূর্ণ কারণ আমরা দুটি ভিন্ন আউটপুট পেয়েছি।সবচেয়ে খারাপ ক্ষেত্রে, যদি আমরা চেষ্টা করি প্রতিটি ইনপুটের জন্য একই আউটপুট দেখতে থাকি, তাহলে $f(x)$ ধ্রুবক রয়েছে তা নিশ্চিত করার জন্য আমাদের সম্ভাব্য সমস্ত ইনপুটের অর্ধেক এবং একটি পরীক্ষা করতে হবে। যেহেতু সম্ভাব্য ইনপুটগুলির মোট সংখ্যা হল $2^n$, এর অর্থ হল যে $2^{n-1}+1$ ট্রায়াল ইনপুট প্রয়োজন তা নিশ্চিত হতে যে $f(x)$ সবচেয়ে খারাপ ক্ষেত্রে ধ্রুবক। উদাহরণস্বরূপ, একটি $4$-বিট স্ট্রিংয়ের জন্য, যদি আমরা $16$ সম্ভাব্য সংমিশ্রণগুলির মধ্যে $8$ চেক করি, সমস্ত $0$ পেয়ে থাকি, তবুও এটি সম্ভব যে $9^\textrm{th}$ ইনপুট একটি $1$ প্রদান করে। এবং $f(x)$ ভারসাম্যপূর্ণ। সম্ভবত, এটি একটি খুব অসম্ভাব্য ঘটনা। প্রকৃতপক্ষে, যদি আমরা ধারাবাহিকভাবে একই ফলাফল পাই, তাহলে আমরা সম্ভাব্যতা প্রকাশ করতে পারি যে ফাংশনটি $k$ ইনপুটগুলির একটি ফাংশন হিসাবে ধ্রুবক থাকে:$$ P_\textrm{constant}(k) = 1 - \frac{1}{2^{k-1}} \qquad \textrm{for } 1 &lt; k \leq 2^{n-1}$$বাস্তবসম্মতভাবে, আমরা আমাদের ক্লাসিক্যাল অ্যালগরিদমকে প্রথম দিকে ছেঁটে ফেলতে বেছে নিতে পারি, বলুন যদি আমরা x%-এর বেশি আত্মবিশ্বাসী হতাম। কিন্তু যদি আমরা 100% আত্মবিশ্বাসী হতে চাই, তাহলে আমাদের $2^{n-1}+1$ ইনপুট চেক করতে হবে।  1.3 কোয়ান্টাম সমাধান একটি কোয়ান্টাম কম্পিউটার ব্যবহার করে, আমরা $f(x)$ ফাংশনে শুধুমাত্র একটি কল করার পরে 100% আত্মবিশ্বাসের সাথে এই সমস্যার সমাধান করতে পারি, তবে আমাদের কাছে $f$ ফাংশনটি কোয়ান্টাম ওরাকল হিসাবে বাস্তবায়িত আছে, যা $\vert x রাষ্ট্রকে ম্যাপ করে। \rangle \vert y\rangle $ থেকে $ \vert x\rangle \vert y \oplus f(x)\rangle$, যেখানে $\oplus$ যোগ মডিউল $2$। নিচে Deutsch-Jozsa অ্যালগরিদমের জন্য জেনেরিক সার্কিট দেওয়া হল।![image1](images/deutsch_steps.png)এখন, অ্যালগরিদটি ধাপে ধাপে করা যাক:   দুটি কোয়ান্টাম রেজিস্টার প্রস্তুত করুন। প্রথমটি হল একটি $n$-qubit রেজিস্টার $|0\rangle$ এ আরম্ভ করা হয়েছে এবং দ্বিতীয়টি হল $|1\rangle$ এ আরম্ভ করা এক-কুবিট রেজিস্টার:$$\vert \psi_0 \rangle = \vert0\rangle^{\otimes n} \vert 1\rangle$$      প্রতিটি কিউবিটে একটি হাদামার্ড গেট প্রয়োগ করুন:$$\vert \psi_1 \rangle = \frac{1}{\sqrt{2^{n+1}}}\sum_{x=0}^{2^n-1} \vert x\rangle \left(|0\rangle - |1 \rangle \right)$$      কোয়ান্টাম ওরাকল $\vert x\rangle \vert y\rangle$ $\vert x\rangle \vert y \oplus f(x)\rangle$: $$ \begin{aligned} \lvert \psi_2 \rangle &amp; এ প্রয়োগ করুন = frac{1}{\sqrt{2^{n+1}}}\sum_{x=0}^{2^n-1} \vert x\rangle (\vert f(x)\rangle - \ vert 1 \oplus f(x)\rangle) \\ &amp; = \frac{1}{\sqrt{2^{n+1}}}\sum_{x=0}^{2^n-1}(- 1)^{f(x)}|x\rangle ( |0\rangle - |1\rangle ) \end{aligned} $$যেহেতু প্রতিটি $x,f(x)$ এর জন্য হয় $0$ বা $1$।      এই সময়ে দ্বিতীয় একক কিউবিট রেজিস্টার উপেক্ষা করা যেতে পারে। প্রথম রেজিস্টারে প্রতিটি কিউবিটে একটি হাডামার্ড গেট প্রয়োগ করুন: $$ \begin{aligned} \lvert \psi_3 \rangle &amp; = \frac{1}{2^n}\sum_{x=0}^{2^n- 1}(-1)^{f(x)} \left[ \sum_{y=0}^{2^n-1}(-1)^{x \cdot y} \vert y \rangle \right] \\ &amp; = \frac{1}{2^n}\sum_{y=0}^{2^n-1} \left[ \sum_{x=0}^{2^n-1}(-1 )^{f(x)}(-1)^{x \cdot y} \right] \vert y \rangle \end{aligned} $$যেখানে $x \cdot y = x_0y_0 \oplus x_1y_1 \oplus \ldots \oplus x_{n-1}y_{n-1}$ হল বিটওয়াইজ পণ্যের সমষ্টি।      প্রথম নিবন্ধন পরিমাপ. লক্ষ্য করুন যে $\vert 0 \rangle ^{\otimes n} = \lvert \frac{1}{2^n}\sum_{x=0}^{2^n-1}(-1) পরিমাপের সম্ভাবনা ^{f(x)} \rvert^2$, যা $f(x)$ ধ্রুবক হলে $1$ এবং $f(x)$ ভারসাম্য থাকলে $0$ মূল্যায়ন করে। 1.4 কেন এটি কাজ করে? - **ধ্রুবক ওরাকল**ওরাকল যখন *ধ্রুবক থাকে* , তখন ইনপুট কিউবিটগুলিতে এটির কোন প্রভাব থাকে না (একটি বিশ্বব্যাপী পর্যায় পর্যন্ত), এবং ওরাকলকে জিজ্ঞাসা করার আগে এবং পরে কোয়ান্টাম অবস্থা একই থাকে। যেহেতু H-গেট তার নিজস্ব বিপরীত, ধাপ 4-এ আমরা প্রথম রেজিস্টারে $|00\dots 0\rangle$-এর প্রাথমিক কোয়ান্টাম অবস্থা পেতে ধাপ 2কে বিপরীত করি। $$ H^{\otimes n}\begin{bmatrix} 1 \ 0 \ 0 \ \vdots \ 0 \end{bmatrix} \tfrac{1}{\sqrt{2^n}}\begin{bmatrix} 1 \ 1 \ 1 \ \vdots \ 1 \end{bmatrix} \quad \xrightarrow{\text{after } U_f} \quad H^{\otimes n}\tfrac{1}{\sqrt{2^n}}\begin{bmatrix} 1 \ 1 \ 1 \ \vdots \ 1 \end{bmatrix}\begin{bmatrix} 1 \ 0 \ 0 \ \vdots \ 0 \end{bmatrix} $$- **সুষম ওরাকল**ধাপ 2 এর পরে, আমাদের ইনপুট রেজিস্টার গণনাগত ভিত্তিতে সমস্ত রাজ্যের সমান সুপারপজিশন। যখন ওরাকল *ভারসাম্যপূর্ণ* হয়, তখন ফেজ কিকব্যাক ঠিক অর্ধেক এই অবস্থাতে একটি নেতিবাচক পর্যায় যোগ করে: $$ U_f \tfrac{1}{\sqrt{2^n}}\begin{bmatrix} 1 \ 1 \ 1 \ \vdots \ 1 \end{bmatrix}\tfrac{1}{\sqrt{2^n}}\begin{bmatrix} -1 \ 1 \ -1 \ \vdots \ 1 \end{bmatrix} $$ওরাকলকে জিজ্ঞাসা করার পরে কোয়ান্টাম অবস্থা ওরাকলকে জিজ্ঞাসা করার আগে কোয়ান্টাম অবস্থার অর্থোগোনাল। এইভাবে, ধাপ 4-এ, H-গেটগুলি প্রয়োগ করার সময়, আমাদের অবশ্যই একটি কোয়ান্টাম অবস্থার সাথে শেষ করতে হবে যা $|00\dots 0\rangle$ এর অর্থোগোনাল। এর মানে আমাদের কখনই অল-জিরো স্টেট পরিমাপ করা উচিত নয়।  2. উদাহরণচলুন দুই বিট ব্যালেন্সড ফাংশনের জন্য একটি নির্দিষ্ট উদাহরণ দেওয়া যাক:একটি দুই-বিট ফাংশন বিবেচনা করুন $f(x_0,x_1)=x_0 \oplus x_1$ যেমন$f(0,0)=0$$f(0,1)=1$$f(1,0)=1$$f(1,1)=0$এই দুই-বিট ওরালসের সংশ্লিষ্ট ফেজ ওরাকল হল $U_f \lvert x_1, x_0 \rangle = (-1)^{f(x_1, x_0)}\lvert x \rangle$$$\lvert \psi_0 \rangle = \lvert 0 0 \rangle_{01} \otimes \lvert 1 \rangle_{2} $$ উদাহরণ দিয়ে এই ওরাকলটি প্রত্যাশা অনুযায়ী কাজ করে কিনা তা আমরা এখন পরীক্ষা করব।    দুটি কিউবিটের প্রথম রেজিস্টার $|00\rangle$ এবং দ্বিতীয় রেজিস্টার qubit $|1\rangle$ এ শুরু করা হয়(উল্লেখ্য যে আমরা কিউবিট সূচী করতে সাবস্ক্রিপ্ট 0, 1, এবং 2 ব্যবহার করছি। "01" এর একটি সাবস্ক্রিপ্ট 0 এবং 1 কিউবিট ধারণকারী রেজিস্টারের অবস্থা নির্দেশ করে)$$\lvert \psi_0 \rangle = \lvert 0 0 \rangle_{01} \otimes \lvert 1 \rangle_{2} $$      সমস্ত কিউবিটে হাদমার্ড প্রয়োগ করুন$$\lvert \psi_1 \rangle = \frac{1}{2} \left( \lvert 0 0 \rangle + \lvert 0 1 \rangle + \lvert 1 0 \rangle + \lvert 1 1 \rangle \right)*{01} \otimes \frac{1}{\sqrt{2}} \left( \lvert 0 \rangle - \lvert 1 \rangle \right)*{2}  $$      ওরাকল ফাংশন $\text{Q}_f = CX_{02}CX_{12}$, $$ \begin{aligned} \lvert \psi_2 \rangle = \frac{1}{2\sqrt{2 হিসাবে প্রয়োগ করা যেতে পারে }} \left[ \lvert 0 0 \rangle_{01} \otimes \left( \lvert 0 \oplus 0 \oplus 0 \rangle - \lvert 1 \oplus 0 \oplus 0 \rangle \right)_{2} \ \ + \lvert 0 1 \rangle_{01} \otimes \left( \lvert 0 \oplus 0 \oplus 1 \rangle - \lvert 1 \oplus 0 \oplus 1 \rangle \right)_{2} \\ + \ lvert 1 0 \rangle_{01} \otimes \left( \lvert 0 \oplus 1 \oplus 0 \rangle - \lvert 1 \oplus 1 \oplus 0 \rangle \right)_{2} \\ + \lvert 1 1 \rangle_{01} \otimes \left( \lvert 0 \oplus 1 \oplus 1 \rangle - \lvert 1 \oplus 1 \oplus 1 \rangle \right)_{2} \right] \end{aligned} $$   এটিকে সহজ করে, আমরা নিম্নলিখিতগুলি পাই: $$ \begin{aligned} \lvert \psi_2 \rangle &amp; = \frac{1}{2\sqrt{2}} \left[ \lvert 0 0 \rangle_{01} \otimes \left( \lvert 0 \rangle - \lvert 1 \rangle \right)_{2} - \lvert 0 1 \rangle_{01} \otimes \left( \lvert 0 \rangle - \lvert 1 \rangle \right) _{2} - \lvert 1 0 \rangle_{01} \otimes \left( \lvert 0 \rangle - \lvert 1 \rangle \right)_{2} + \lvert 1 1 \rangle_{01} \otimes \ বাম( \lvert 0 \rangle - \lvert 1 \rangle \right)_{2} \right] \\ &amp; = \frac{1}{2} \left( \lvert 0 0 \rangle - \lvert 0 1 \ rangle - \lvert 1 0 \rangle + \lvert 1 1 \rangle \right)_{01} \otimes \frac{1}{\sqrt{2}} \left( \lvert 0 \rangle - \lvert 1 \rangle \right)_{2} \\ &amp; = \frac{1}{\sqrt{2}} \left( \lvert 0 \rangle - \lvert 1 \rangle \right)_{0} \otimes \frac{1 }{\sqrt{2}} \left( \lvert 0 \rangle - \lvert 1 \rangle \right)_{1} \otimes \frac{1}{\sqrt{2}} \left( \lvert 0 \ rangle - \lvert 1 \rangle \right)_{2} \end{aligned} $$   প্রথম রেজিস্টারে হাদমার্ড প্রয়োগ করুন$$ \lvert \psi_3\rangle = \lvert 1 \rangle_{0} \otimes \lvert 1 \rangle_{1} \otimes \left( \lvert 0 \rangle - \lvert 1 \rangle \right)_{2} $$      প্রথম দুটি কিউবিট পরিমাপ করলে অ-শূন্য $11$ দেবে, একটি সুষম ফাংশন নির্দেশ করে।আপনি নীচের উইজেট ব্যবহার করে অনুরূপ উদাহরণ চেষ্টা করতে পারেন. এইচ-গেট এবং ওরাকল যোগ করতে বোতাম টিপুন, সেলটি পুনরায় চালান এবং/অথবা বিভিন্ন ওরাকল চেষ্টা করার জন্য `case="constant"` সেট করুন।<jupyter_code>from qiskit_textbook.widgets import dj_widget
dj_widget(size="small", case="balanced")<jupyter_output><empty_output><jupyter_text>3. কোয়ান্টাম ওরাকল তৈরি করা আসুন কিছু ভিন্ন উপায় দেখি আমরা একটি কোয়ান্টাম ওরাকল তৈরি করতে পারি।একটি ধ্রুবক ফাংশনের জন্য, এটি সহজ:$\qquad$ 1. যদি f(x) = 0 হয়, তাহলে রেজিস্টার 2-এর qubit-এ $I$ গেট প্রয়োগ করুন। $\qquad$ 2. যদি f(x) = 1 হয়, তাহলে রেজিস্টার 2-এর qubit-এ $X$ গেট প্রয়োগ করুন।একটি ভারসাম্যপূর্ণ ফাংশন জন্য, আমরা তৈরি করতে পারেন অনেক বিভিন্ন সার্কিট আছে. আমাদের সার্কিট ভারসাম্যের গ্যারান্টি দেওয়ার একটি উপায় হল রেজিস্টার 1-এ প্রতিটি কিউবিটের জন্য একটি সিএনওটি সম্পাদন করা, রেজিস্টার 2-এর কিউবিটকে লক্ষ্য হিসাবে। উদাহরণ স্বরূপ:![image2](images/deutsch_balanced1.svg)উপরের ছবিতে, উপরের তিনটি কিউবিট ইনপুট রেজিস্টার গঠন করে এবং নীচের কিউবিটটি আউটপুট রেজিস্টার। নিচের টেবিলে আমরা দেখতে পাচ্ছি কোন ইনপুট স্টেট কোন আউটপুট দেয়:ইনপুট বলে যে আউটপুট 0 | ইনপুট স্টেটস যে আউটপুট 1:-: | :-:000 | 001011 | 100101 | 010110 | 111আমরা এক্স-গেটগুলিতে নির্বাচিত নিয়ন্ত্রণগুলি মোড়ানোর মাধ্যমে ভারসাম্য বজায় রেখে ফলাফলগুলি পরিবর্তন করতে পারি। উদাহরণস্বরূপ, সার্কিট এবং নীচের ফলাফল টেবিল দেখুন:![other_balanced_circuit](images/deutsch_balanced2.svg)ইনপুট বলে যে আউটপুট 0 | ইনপুট বলে যে আউটপুট 1:-: | :-:001 | 000010 | 011100 | 101111 | 110  4. কিস্কিট বাস্তবায়নআমরা এখন একটি থ্রি-বিট ফাংশনের উদাহরণের জন্য Deutsch-Jozsa অ্যালগরিদম বাস্তবায়ন করি, উভয় ধ্রুবক এবং ভারসাম্যপূর্ণ ওরাকল সহ। প্রথমে আমাদের আমদানি করা যাক:<jupyter_code># initialization
import numpy as np

# importing Qiskit
from qiskit import IBMQ, Aer
from qiskit.providers.ibmq import least_busy
from qiskit import QuantumCircuit, transpile

# import basic plot tools
from qiskit.visualization import plot_histogram<jupyter_output><empty_output><jupyter_text>এর পরে, আমরা আমাদের ওরাকলের জন্য ইনপুট রেজিস্টারের আকার সেট করি:<jupyter_code># set the length of the n-bit input string. 
n = 3<jupyter_output><empty_output><jupyter_text>4.1 ধ্রুবক ওরাকলচলুন একটি ধ্রুবক ওরাকল তৈরি করে শুরু করা যাক, এই ক্ষেত্রে ইনপুট আউটপুটে কোন প্রভাব ফেলবে না তাই আমরা এলোমেলোভাবে আউটপুট qubit কে 0 বা 1 এ সেট করেছি:<jupyter_code># set the length of the n-bit input string. 
n = 3

const_oracle = QuantumCircuit(n+1)

output = np.random.randint(2)
if output == 1:
    const_oracle.x(n)

const_oracle.draw()<jupyter_output><empty_output><jupyter_text>4.2 সুষম ওরাকল<jupyter_code>balanced_oracle = QuantumCircuit(n+1)<jupyter_output><empty_output><jupyter_text>এর পরে, আমরা একটি সুষম ওরাকল তৈরি করি। যেমনটি আমরা বিভাগ 1b-এ দেখেছি, আমরা প্রতিটি ইনপুট কিউবিটকে নিয়ন্ত্রণ হিসাবে এবং আউটপুট বিটকে লক্ষ্য হিসাবে CNOTs সম্পাদন করে একটি ভারসাম্যপূর্ণ ওরাকল তৈরি করতে পারি। আমরা এক্স-গেটগুলিতে কিছু নিয়ন্ত্রণ মোড়ানোর মাধ্যমে 0 বা 1 দেওয়ার ইনপুট স্টেটগুলি পরিবর্তন করতে পারি। আসুন প্রথমে দৈর্ঘ্যের একটি `n` স্ট্রিং বেছে নেওয়া যাক যা নির্দেশ করে যে কোনটি মোড়ানো হবে:<jupyter_code>b_str = "101"<jupyter_output><empty_output><jupyter_text>এখন আমাদের কাছে এই স্ট্রিংটি রয়েছে, আমরা এটিকে আমাদের এক্স-গেট স্থাপনের জন্য একটি কী হিসাবে ব্যবহার করতে পারি। আমাদের সার্কিটের প্রতিটি কিউবিটের জন্য, আমরা একটি X-গেট রাখি যদি `b_str` এ সংশ্লিষ্ট সংখ্যা `1` হয়, অথবা অঙ্কটি `0` হলে কিছুই করি না।<jupyter_code>balanced_oracle = QuantumCircuit(n+1)
b_str = "101"

# Place X-gates
for qubit in range(len(b_str)):
    if b_str[qubit] == '1':
        balanced_oracle.x(qubit)
balanced_oracle.draw()<jupyter_output><empty_output><jupyter_text>এর পরে, আমরা প্রতিটি ইনপুট কিউবিটকে নিয়ন্ত্রণ হিসাবে এবং আউটপুট কিউবিটকে লক্ষ্য হিসাবে ব্যবহার করে আমাদের নিয়ন্ত্রিত-নট গেটগুলি করি:<jupyter_code>balanced_oracle = QuantumCircuit(n+1)
b_str = "101"

# Place X-gates
for qubit in range(len(b_str)):
    if b_str[qubit] == '1':
        balanced_oracle.x(qubit)

# Use barrier as divider
balanced_oracle.barrier()

# Controlled-NOT gates
for qubit in range(n):
    balanced_oracle.cx(qubit, n)

balanced_oracle.barrier()
balanced_oracle.draw()<jupyter_output><empty_output><jupyter_text>অবশেষে, এক্স-গেটগুলিতে নিয়ন্ত্রণগুলি মোড়ানো শেষ করতে আমরা দুটি কক্ষ থেকে কোডটি পুনরাবৃত্তি করি:<jupyter_code>balanced_oracle = QuantumCircuit(n+1)
b_str = "101"

# Place X-gates
for qubit in range(len(b_str)):
    if b_str[qubit] == '1':
        balanced_oracle.x(qubit)

# Use barrier as divider
balanced_oracle.barrier()

# Controlled-NOT gates
for qubit in range(n):
    balanced_oracle.cx(qubit, n)

balanced_oracle.barrier()

# Place X-gates
for qubit in range(len(b_str)):
    if b_str[qubit] == '1':
        balanced_oracle.x(qubit)

# Show oracle
balanced_oracle.draw()<jupyter_output><empty_output><jupyter_text>আমরা শুধু একটি সুষম ওরাকল তৈরি করেছি! ডয়েচ-জোজসা অ্যালগরিদম এটি সমাধান করতে পারে কিনা তা দেখতে বাকি আছে। 4.3 সম্পূর্ণ অ্যালগরিদমএখন সবকিছু একসাথে করা যাক. অ্যালগরিদমের এই প্রথম ধাপটি হল ইনপুট কিউবিট স্টেট $|{+}\rangle$ এবং আউটপুট কিউবিট স্টেটে $|{-}\rangle$:<jupyter_code>dj_circuit = QuantumCircuit(n+1, n)

# Apply H-gates
for qubit in range(n):
    dj_circuit.h(qubit)

# Put qubit in state |->
dj_circuit.x(n)
dj_circuit.h(n)
dj_circuit.draw()<jupyter_output><empty_output><jupyter_text>এর পরে, এর ওরাকল প্রয়োগ করা যাক। এখানে আমরা উপরে তৈরি করা `balanced_oracle` প্রয়োগ করি:<jupyter_code>dj_circuit = QuantumCircuit(n+1, n)

# Apply H-gates
for qubit in range(n):
    dj_circuit.h(qubit)

# Put qubit in state |->
dj_circuit.x(n)
dj_circuit.h(n)

# Add oracle
dj_circuit = dj_circuit.compose(balanced_oracle)
dj_circuit.draw()<jupyter_output><empty_output><jupyter_text>অবশেষে, আমরা $n$-ইনপুট কিউবিটগুলিতে H-গেটগুলি সম্পাদন করি এবং আমাদের ইনপুট রেজিস্টার পরিমাপ করি:<jupyter_code>dj_circuit = QuantumCircuit(n+1, n)

# Apply H-gates
for qubit in range(n):
    dj_circuit.h(qubit)

# Put qubit in state |->
dj_circuit.x(n)
dj_circuit.h(n)

# Add oracle
dj_circuit = dj_circuit.compose(balanced_oracle)

# Repeat H-gates
for qubit in range(n):
    dj_circuit.h(qubit)
dj_circuit.barrier()

# Measure
for i in range(n):
    dj_circuit.measure(i, i)

# Display circuit
dj_circuit.draw()<jupyter_output><empty_output><jupyter_text>চলুন আউটপুট দেখিঃ<jupyter_code># use local simulator
aer_sim = Aer.get_backend('aer_simulator')
results = aer_sim.run(dj_circuit).result()
answer = results.get_counts()

plot_histogram(answer)<jupyter_output><empty_output><jupyter_text>আমরা উপরের ফলাফলগুলি থেকে দেখতে পাচ্ছি যে আমাদের `000` পরিমাপের 0% সম্ভাবনা রয়েছে। এটি সঠিকভাবে ভবিষ্যদ্বাণী করে যে ফাংশনটি ভারসাম্যপূর্ণ। 4.4 সাধারণ সার্কিটনীচে, আমরা একটি সাধারণ ফাংশন প্রদান করি যা ডয়েচ-জোজসা ওরাকল তৈরি করে এবং তাদের কোয়ান্টাম গেটে পরিণত করে। এটি `case` লাগে, (হয় `'balanced'` বা ' `constant` ', এবং `n` , ইনপুট রেজিস্টারের আকার:<jupyter_code>def dj_oracle(case, n):
    # We need to make a QuantumCircuit object to return
    # This circuit has n+1 qubits: the size of the input,
    # plus one output qubit
    oracle_qc = QuantumCircuit(n+1)
    
    # First, let's deal with the case in which oracle is balanced
    if case == "balanced":
        # First generate a random number that tells us which CNOTs to
        # wrap in X-gates:
        b = np.random.randint(1,2**n)
        # Next, format 'b' as a binary string of length 'n', padded with zeros:
        b_str = format(b, '0'+str(n)+'b')
        # Next, we place the first X-gates. Each digit in our binary string 
        # corresponds to a qubit, if the digit is 0, we do nothing, if it's 1
        # we apply an X-gate to that qubit:
        for qubit in range(len(b_str)):
            if b_str[qubit] == '1':
                oracle_qc.x(qubit)
        # Do the controlled-NOT gates for each qubit, using the output qubit 
        # as the target:
        for qubit in range(n):
            oracle_qc.cx(qubit, n)
        # Next, place the final X-gates
        for qubit in range(len(b_str)):
            if b_str[qubit] == '1':
                oracle_qc.x(qubit)

    # Case in which oracle is constant
    if case == "constant":
        # First decide what the fixed output of the oracle will be
        # (either always 0 or always 1)
        output = np.random.randint(2)
        if output == 1:
            oracle_qc.x(n)
    
    oracle_gate = oracle_qc.to_gate()
    oracle_gate.name = "Oracle" # To show when we display the circuit
    return oracle_gate<jupyter_output><empty_output><jupyter_text>আসুন একটি ফাংশন তৈরি করি যা এই ওরাকল গেটটি নেয় এবং এটিতে ডয়েচ-জোজসা অ্যালগরিদম সম্পাদন করে:<jupyter_code>def dj_algorithm(oracle, n):
    dj_circuit = QuantumCircuit(n+1, n)
    # Set up the output qubit:
    dj_circuit.x(n)
    dj_circuit.h(n)
    # And set up the input register:
    for qubit in range(n):
        dj_circuit.h(qubit)
    # Let's append the oracle gate to our circuit:
    dj_circuit.append(oracle, range(n+1))
    # Finally, perform the H-gates again and measure:
    for qubit in range(n):
        dj_circuit.h(qubit)
    
    for i in range(n):
        dj_circuit.measure(i, i)
    
    return dj_circuit<jupyter_output><empty_output><jupyter_text>অবশেষে, আসুন অ্যালগরিদমের সাথে খেলার জন্য এই ফাংশনগুলি ব্যবহার করি:<jupyter_code>n = 4
oracle_gate = dj_oracle('balanced', n)
dj_circuit = dj_algorithm(oracle_gate, n)
dj_circuit.draw()<jupyter_output><empty_output><jupyter_text>এবং এই সার্কিট চালানোর ফলাফল দেখুন:<jupyter_code>transpiled_dj_circuit = transpile(dj_circuit, aer_sim)
results = aer_sim.run(transpiled_dj_circuit).result()
answer = results.get_counts()
plot_histogram(answer)<jupyter_output><empty_output><jupyter_text>5. বাস্তব ডিভাইসের সাথে পরীক্ষাআমরা নিচের চিত্রের মতো বাস্তব ডিভাইসে সার্কিট চালাতে পারি। আমরা প্রথমে আমাদের সার্কিট পরিচালনা করতে পারে এমন কম-ব্যস্ত ডিভাইসটি সন্ধান করি।<jupyter_code># Load our saved IBMQ accounts and get the least busy backend device with greater than or equal to (n+1) qubits
IBMQ.load_account()
provider = IBMQ.get_provider(hub='ibm-q')
backend = least_busy(provider.backends(filters=lambda x: x.configuration().n_qubits >= (n+1) and
                                   not x.configuration().simulator and x.status().operational==True))
print("least busy backend: ", backend)
# Run our circuit on the least busy backend. Monitor the execution of the job in the queue
from qiskit.tools.monitor import job_monitor

transpiled_dj_circuit = transpile(dj_circuit, backend, optimization_level=3)
job = backend.run(transpiled_dj_circuit)
job_monitor(job, interval=2)
# Get the results of the computation
results = job.result()
answer = results.get_counts()

plot_histogram(answer)<jupyter_output><empty_output><jupyter_text>আমরা দেখতে পাচ্ছি, সবচেয়ে সম্ভাব্য ফলাফল হল `1111` । অন্যান্য ফলাফলগুলি কোয়ান্টাম গণনার ত্রুটির কারণে।   6. সমস্যা1. আপনি একটি ভিন্ন ফর্ম একটি সুষম বা ধ্রুবক ওরাকল তৈরি করতে সক্ষম?2. ফাংশন `dj_problem_oracle` (নীচে) একটি গেট আকারে `n = 4` এর জন্য একটি Deutsch-Jozsa oracle প্রদান করে। গেটটি ইনপুট হিসাবে 5 কিউবিট নেয় যেখানে চূড়ান্ত qubit ( `q_4` ) হল আউটপুট qubit (উপরের ওরাকলের উদাহরণ হিসাবে)। আপনি `dj_problem_oracle` 1 এবং 5 এর মধ্যে বিভিন্ন পূর্ণসংখ্যা দিয়ে বিভিন্ন ওরাকল পেতে পারেন। প্রতিটি ওরাকল ভারসাম্যপূর্ণ বা ধ্রুবক কিনা তা নির্ধারণ করতে Deutsch-Jozsa অ্যালগরিদম ব্যবহার করুন ( **দ্রষ্টব্য:** এটি অত্যন্ত সুপারিশ করা হয় যে আপনি একটি বাস্তব ডিভাইসের পরিবর্তে `aer_simulator` ব্যবহার করে এই উদাহরণটি ব্যবহার করে দেখুন) .<jupyter_code>from qiskit_textbook.problems import dj_problem_oracle
oracle = dj_problem_oracle(1)<jupyter_output><empty_output><jupyter_text>7. References 1. <NAME> and <NAME> (1992). "Rapid solutions of problems by quantum computation". Proceedings of the Royal Society of London A. 439: 553–558.  [doi:10.1098/rspa.1992.0167](https://doi.org/10.1098%2Frspa.1992.0167).2. <NAME>; <NAME>; <NAME>; <NAME> (1998). "Quantum algorithms revisited". Proceedings of the Royal Society of London A. 454: 339–354. [doi:10.1098/rspa.1998.0164](https://doi.org/10.1098%2Frspa.1998.0164).<jupyter_code>import qiskit.tools.jupyter
%qiskit_version_table<jupyter_output>/usr/local/anaconda3/envs/terra-unstable/lib/python3.9/site-packages/qiskit/aqua/__init__.py:86: DeprecationWarning: The package qiskit.aqua is deprecated. It was moved/refactored to qiskit-terra For more information see <https://github.com/Qiskit/qiskit-aqua/blob/main/README.md#migration-guide>
  warn_package('aqua', 'qiskit-terra')
{'fraction_non_alphanumeric': 0.23031974569932684, 'fraction_numerical': 0.02804786836200449, 'mean_word_length': 4.337574850299402, 'pattern_counts': {'":': 2, '<': 87, '<?xml version=': 0, '>': 91, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '20', 'dir': 'jupyter-structured-clean-dedup', 'id': '404193', 'license': 'Apache-2.0', 'n_tokens_mistral': 14817, 'n_tokens_neox': 16485, 'n_words': 2504, 'path': 'translations/bn/ch-algorithms/deutsch-jozsa.ipynb', 'repo_name': 'qiskit-community/platypus', 'size': '21421'}