1 //---------------------------------------------------------------------------
\r
2 // Show qubits' states
\r
3 //---------------------------------------------------------------------------
\r
7 //using namespace std;
\r
13 #include <algorithm>
\r
16 #include "QDrawGraph.h"
\r
17 //---------------------------------------------------------------------------
\r
18 #pragma package(smart_init)
\r
19 //---------------------------------------------------------------------------
\r
20 const double QDrawGraph::EPS = 1.0e-10; // Cut-off for showing non-zero
\r
21 //---------------------------------------------------------------------------
\r
25 QDrawGraph::QDrawGraph(TCanvas *_Canvas) {
\r
30 mTopWindowMargin = 30;
\r
41 SetFontSizeOfQbit(14);
\r
42 SetFontSizeOfValue(14);
\r
45 //---------------------------------------------------------------------------
\r
49 QDrawGraph::~QDrawGraph() {
\r
51 //---------------------------------------------------------------------------
\r
56 QDrawGraph::DrawAll(const QBits *qbits, const int type) {
\r
58 mCanvas->Brush->Color = clWhite;
\r
59 mCanvas->FillRect(Rect(0,0,mImageWidth,mImageHeight));
\r
61 int num_state = qbits->GetNumberOfStates();
\r
62 for (int i = 0; i < num_state; i++) {
\r
63 DrawNthRow(qbits, i, i);
\r
66 //---------------------------------------------------------------------------
\r
68 * Draw Only NonZero States
\r
71 QDrawGraph::DrawNonZero(const QBits *qbits) {
\r
72 mCanvas->Brush->Color = clWhite;
\r
73 mCanvas->FillRect(Rect(0,0,mImageWidth,mImageHeight));
\r
75 std::vector<int> vq;
\r
76 for (int i=0;i<qbits->GetNumberOfStates();i++) {
\r
77 double re = qbits->NthStateR(i);
\r
78 double im = qbits->NthStateI(i);
\r
79 if (re*re+im*im > EPS) {
\r
83 for (int i=0;i<(int)vq.size();i++) {
\r
84 DrawNthRow(qbits,vq[i],i);
\r
87 //---------------------------------------------------------------------------
\r
92 QDrawGraph::Paint(const QBits *qbits) {
\r
93 switch (GetDrawMode()) {
\r
102 //---------------------------------------------------------------------------
\r
104 QDrawGraph::SetDrawMode(int Mode,const QBits *qbits) {
\r
108 switch (GetDrawMode()) {
\r
113 SetSizeNonZero(qbits);
\r
117 //---------------------------------------------------------------------------
\r
119 QDrawGraph::SetSize(const QBits *qbits) {
\r
121 int num_state = qbits->GetNumberOfStates();
\r
122 SetPageFormat(qbits);
\r
124 mWidth = mLeftMargin + mWidthOfIndex + mIAMargin + mWidthOfArrow + mAVMargin
\r
125 + mWidthOfValue + mVQMargin + mWidthOfQbits + mRightMargin;
\r
126 mHeight = mTopMargin + num_state * (mRowMargin + GetRowHeight())
\r
127 + mBottomMargin + mTopMargin + mTopWindowMargin;
\r
129 if (mHeight < mImageHeight)mHeight = mImageHeight;
\r
131 //---------------------------------------------------------------------------
\r
133 QDrawGraph::SetViewingTop(int t) {
\r
136 } else if (t > (mHeight- mImageHeight)) {
\r
137 t = (mHeight- mImageHeight);
\r
141 //---------------------------------------------------------------------------
\r
143 * Get size to show only non-zero states
\r
146 QDrawGraph::SetSizeNonZero(const QBits *qbits) {
\r
148 int num_state = GetNonZeroCount(qbits);
\r
149 SetPageFormat(qbits);
\r
151 mWidth = mLeftMargin + mWidthOfIndex + mIAMargin + mWidthOfArrow + mAVMargin
\r
152 + mWidthOfValue + mVQMargin + mWidthOfQbits + mRightMargin;
\r
153 mHeight = mTopMargin + num_state * (mRowMargin + GetRowHeight())
\r
154 + mBottomMargin + mTopMargin + mTopWindowMargin;
\r
156 if (mHeight < mImageHeight)mHeight = mImageHeight;
\r
159 //---------------------------------------------------------------------------
\r
160 // Utility functions
\r
161 //---------------------------------------------------------------------------
\r
163 //---------------------------------------------------------------------------
\r
165 QDrawGraph::GetRowHeight(void) const {
\r
167 max_height = mHeightOfArrow >= mHeightOfValue ? mHeightOfArrow : mHeightOfValue;
\r
168 max_height = max_height >= mHeightOfQbits ? max_height : mHeightOfQbits;
\r
169 max_height = max_height >= mHeightOfIndex ? max_height : mHeightOfIndex;
\r
172 //---------------------------------------------------------------------------
\r
177 QDrawGraph::SetPageFormat(const QBits *qbits) {
\r
178 const double LOG10 = 2.3025850929940456840179914546844;
\r
179 int num_state = qbits->GetNumberOfStates();
\r
180 int num_qbits = qbits->GetNumberOfQBits();
\r
183 mWidthOfArrow = mHeightOfArrow = mSizeOfArrow;
\r
185 int num_index = (int)(std::log((double)num_state)/LOG10) + 1;
\r
186 AnsiString as1 = "";
\r
187 for (int i = 0; i < num_index; i++) as1 += "0";
\r
188 mCanvas->Font->Size = FSIZE_INDEX;
\r
189 mWidthOfIndex = mCanvas->TextWidth(as1);
\r
190 mHeightOfIndex = mCanvas->TextHeight("0");
\r
193 as1 = "-- + i..00";
\r
194 for (int i = 0; i < mPrecision; i++) as1 += "00";
\r
195 mCanvas->Font->Size = mFontSizeOfValue;
\r
196 mWidthOfValue = mCanvas->TextWidth(as1);
\r
197 mHeightOfValue = mCanvas->TextHeight("0");
\r
201 for (int i = 0; i < num_qbits; i++) as1 += "0";
\r
203 mCanvas->Font->Size = mFontSizeOfQbit;
\r
204 mWidthOfQbits = mCanvas->TextWidth(as1);
\r
205 mHeightOfQbits = mCanvas->TextHeight("0");
\r
207 //---------------------------------------------------------------------------
\r
212 QDrawGraph::DrawNthRow(const QBits *qbits, const int nq, const int nrow) const {
\r
213 int left, bottom, max_height;
\r
214 //judge whether this qubits is in viewport;
\r
215 int h = mTopMargin + (nrow) * (mRowMargin + GetRowHeight())
\r
216 + mTopMargin + mTopWindowMargin;
\r
217 if (h > mViewingTop+mHeight || h < (mRowMargin+mViewingTop)) {
\r
221 double re = qbits->NthStateR(nq);
\r
222 double im = qbits->NthStateI(nq);
\r
224 max_height = GetRowHeight();
\r
226 left = mLeftMargin;
\r
227 bottom = mTopMargin + max_height + (max_height + mRowMargin ) * nrow;
\r
228 bottom -= mViewingTop;
\r
230 bottom -= mStrOffset;
\r
231 DrawIndex(left, bottom - mHeightOfIndex, nq);
\r
232 bottom += mStrOffset;
\r
233 left += mWidthOfIndex + mIAMargin;
\r
235 DrawArrow(left, bottom - mHeightOfArrow, re, im);
\r
236 bottom -= mStrOffset;
\r
237 left += mWidthOfArrow + mAVMargin;
\r
239 DrawValue(left, bottom - mHeightOfValue, re, im);
\r
240 left += mWidthOfValue + mVQMargin;
\r
241 DrawQbit(left, bottom - mHeightOfQbits, qbits->GetNumberOfQBits(), nq);
\r
243 //---------------------------------------------------------------------------
\r
245 //---------------------------------------------------------------------------
\r
250 QDrawGraph::DrawIndex(const int x, const int y, const int num) const {
\r
251 mCanvas->Brush->Color = clWhite;
\r
252 mCanvas->Font->Color = clBlack;
\r
253 mCanvas->Font->Size = FSIZE_INDEX;
\r
254 mCanvas->TextOut(x, y, IntToStr(num));
\r
256 //---------------------------------------------------------------------------
\r
261 QDrawGraph::DrawArrow(const int x, const int y, const double re, const double im) const {
\r
262 int default_length = mWidthOfArrow / 2;
\r
263 int xfrom = x + default_length;
\r
264 int yfrom = y + default_length;
\r
265 double norm = std::sqrt(re * re + im * im);
\r
267 mCanvas->Brush->Color = clWhite;
\r
268 mCanvas->Pen->Color = clBlack;
\r
269 mCanvas->Pen->Width = 2;
\r
270 mCanvas->Ellipse(x, y, x + mWidthOfArrow, y + mHeightOfArrow);
\r
271 mCanvas->Pen->Color = clRed;
\r
272 mCanvas->MoveTo(xfrom, yfrom);
\r
274 default_length *= 0.9;
\r
276 mCanvas->LineTo(xfrom + default_length * re / norm, yfrom - default_length * im / norm);
\r
278 //---------------------------------------------------------------------------
\r
283 QDrawGraph::DrawValue(const int x, const int y, double re, double im) const {
\r
284 std::stringstream ss;
\r
285 ss << std::setprecision(mPrecision);
\r
286 ss.setf(std::ios::fixed);
\r
296 mCanvas->Brush->Color = clWhite;
\r
297 mCanvas->Font->Color = clRed;
\r
298 mCanvas->Font->Size = mFontSizeOfValue;
\r
299 mCanvas->TextOut(x, y, ss.str().c_str());
\r
301 //---------------------------------------------------------------------------
\r
306 QDrawGraph::DrawQbit(const int x, const int y, const int ntotal, int nth) const {
\r
308 nth = nth < 0 ? -nth : nth;
\r
309 for (int i = 0; i < ntotal; i++) {
\r
310 if ((nth >> i) & 1) s = "1" + s;
\r
314 mCanvas->Brush->Color = clWhite;
\r
315 mCanvas->Font->Color = clBlack;
\r
316 mCanvas->Font->Size = mFontSizeOfQbit;
\r
317 mCanvas->TextOut(x, y, s.c_str());
\r
319 //---------------------------------------------------------------------------
\r
321 * Count How many non-zero number of states
\r
324 QDrawGraph::GetNonZeroCount(const QBits *qbits) {
\r
326 for (int i=0;i<qbits->GetNumberOfStates();i++) {
\r
327 double re = qbits->NthStateR(i);
\r
328 double im = qbits->NthStateI(i);
\r
329 if (re*re+im*im > EPS) {
\r
335 //---------------------------------------------------------------------------
\r