microsoft/qdk

Public

mirrored from https://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.9.0

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

compiler/qsc_eval/src/state/tests.rs

822lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4#![allow(clippy::needless_raw_string_hashes)]
5
6use super::{
7 get_matrix_latex, get_state_latex, write_latex_for_algebraic_number,
8 write_latex_for_cartesian_form, write_latex_for_complex_number, write_latex_for_decimal_number,
9 write_latex_for_polar_form, write_latex_for_real_number, write_latex_for_term, AlgebraicNumber,
10 CartesianForm, ComplexNumber, DecimalNumber, PolarForm, RationalNumber, RealNumber, Term,
11};
12use crate::state::{is_fractional_part_significant, is_significant};
13use expect_test::{expect, Expect};
14use num_complex::Complex64;
15use std::{
16 f64::consts::{FRAC_1_SQRT_2, PI},
17 time::Instant,
18};
19
20#[test]
21fn check_is_significant() {
22 assert!(!is_significant(0.0));
23 assert!(!is_significant(1e-10));
24 assert!(!is_significant(-1e-10));
25 assert!(is_significant(1.1e-9));
26 assert!(is_significant(-1.1e-9));
27 assert!(is_significant(1.0));
28 assert!(is_significant(-1.0));
29}
30
31#[test]
32fn check_is_fractional_part_significant() {
33 assert!(!is_fractional_part_significant(0.0));
34 assert!(!is_fractional_part_significant(1e-10));
35 assert!(!is_fractional_part_significant(-1e-10));
36 assert!(is_fractional_part_significant(1.1e-9));
37 assert!(is_fractional_part_significant(-1.1e-9));
38 assert!(!is_fractional_part_significant(1.000_000_000_1));
39 assert!(!is_fractional_part_significant(-1.000_000_000_1));
40 assert!(is_fractional_part_significant(1.000_000_001));
41 assert!(is_fractional_part_significant(-1.000_000_001));
42}
43
44fn assert_rational_value(x: Option<RationalNumber>, expected: (i64, i64, i64)) {
45 match x {
46 None => panic!("Expected rational number."),
47 Some(r) => assert!(
48 r.sign == expected.0 && r.numerator == expected.1 && r.denominator == expected.2
49 ),
50 }
51}
52
53#[test]
54fn check_construct_rational() {
55 assert_rational_value(Some(RationalNumber::new(1, 2)), (1, 1, 2));
56 assert_rational_value(Some(RationalNumber::new(-1, 2)), (-1, 1, 2));
57 assert_rational_value(Some(RationalNumber::new(1, -2)), (-1, 1, 2));
58 assert_rational_value(Some(RationalNumber::new(-1, -2)), (1, 1, 2));
59 // Although 0 is never used in the code we check it for completeness.
60 assert_rational_value(Some(RationalNumber::new(0, 1)), (0, 0, 1));
61 expect!([r"
62 RationalNumber {
63 sign: 1,
64 numerator: 1,
65 denominator: 2,
66 }
67 "])
68 .assert_debug_eq(&RationalNumber::new(1, 2));
69}
70
71#[test]
72fn check_abs_rational() {
73 assert_rational_value(Some(RationalNumber::new(1, 2).abs()), (1, 1, 2));
74 assert_rational_value(Some(RationalNumber::new(-1, 2).abs()), (1, 1, 2));
75 assert_rational_value(Some(RationalNumber::new(1, -2).abs()), (1, 1, 2));
76 assert_rational_value(Some(RationalNumber::new(-1, -2).abs()), (1, 1, 2));
77 // Although 0 is never used in the code we check it for completeness.
78 assert_rational_value(Some(RationalNumber::new(0, 1).abs()), (0, 0, 1));
79}
80
81#[test]
82fn check_recognize_rational() {
83 assert_rational_value(RationalNumber::recognize(1.0 / 1.0), (1, 1, 1));
84 assert_rational_value(RationalNumber::recognize(1.0 / 2.0), (1, 1, 2));
85 assert_rational_value(RationalNumber::recognize(1.0 / 3.0), (1, 1, 3));
86 assert_rational_value(RationalNumber::recognize(-5.0 / 7.0), (-1, 5, 7));
87 assert!(RationalNumber::recognize(1.0 / 1000.0).is_none());
88 assert!(RationalNumber::recognize(1000.0 / 1.0).is_none());
89 // Although 0 is never used in the code we check it for completeness.
90 assert_rational_value(RationalNumber::recognize(0.0), (0, 0, 1));
91}
92
93fn assert_algebraic_value(x: Option<AlgebraicNumber>, expected: (i64, i64, i64, i64, i64)) {
94 match x {
95 None => panic!("Expected algebraic number."),
96 Some(a) => assert!(
97 a.sign == expected.0
98 && a.fraction.sign == expected.1
99 && a.fraction.numerator == expected.2
100 && a.fraction.denominator == expected.3
101 && a.root == expected.4
102 ),
103 }
104}
105
106#[test]
107fn check_construct_algebraic() {
108 assert_algebraic_value(
109 Some(AlgebraicNumber::new(&RationalNumber::new(1, 2), 3)),
110 (1, 1, 1, 2, 3),
111 );
112 assert_algebraic_value(
113 Some(AlgebraicNumber::new(&RationalNumber::new(-1, 2), 3)),
114 (-1, 1, 1, 2, 3),
115 );
116 assert_algebraic_value(
117 Some(AlgebraicNumber::new(&RationalNumber::new(1, -2), 3)),
118 (-1, 1, 1, 2, 3),
119 );
120 assert_algebraic_value(
121 Some(AlgebraicNumber::new(&RationalNumber::new(-1, -2), 3)),
122 (1, 1, 1, 2, 3),
123 );
124 expect!([r"
125 AlgebraicNumber {
126 sign: 1,
127 fraction: RationalNumber {
128 sign: 1,
129 numerator: 1,
130 denominator: 2,
131 },
132 root: 3,
133 }
134 "])
135 .assert_debug_eq(&AlgebraicNumber::new(&RationalNumber::new(1, 2), 3));
136}
137
138#[test]
139fn check_recognize_algebraic() {
140 assert_algebraic_value(AlgebraicNumber::recognize(5.0), (1, 1, 5, 1, 1));
141 assert_algebraic_value(AlgebraicNumber::recognize(1.0 / 7.0), (1, 1, 1, 7, 1));
142 assert_algebraic_value(AlgebraicNumber::recognize(7.0 / 10.0), (1, 1, 7, 10, 1));
143 assert_algebraic_value(
144 AlgebraicNumber::recognize(2.0 * 2.0_f64.sqrt()),
145 (1, 1, 2, 1, 2),
146 );
147 assert_algebraic_value(AlgebraicNumber::recognize(8.0_f64.sqrt()), (1, 1, 2, 1, 2));
148 assert_algebraic_value(
149 AlgebraicNumber::recognize(5.0_f64.sqrt() / 15.0),
150 (1, 1, 1, 15, 5),
151 );
152 assert_algebraic_value(
153 AlgebraicNumber::recognize(3.0 / 5.0 * 2.0_f64.sqrt()),
154 (1, 1, 3, 5, 2),
155 );
156 assert_algebraic_value(
157 AlgebraicNumber::recognize(-3.0 / 5.0 * 2.0_f64.sqrt()),
158 (-1, 1, 3, 5, 2),
159 );
160}
161
162fn assert_decimal_value(x: &DecimalNumber, expected: (i64, f64)) {
163 assert!(x.sign == expected.0 && (x.value - expected.1).abs() < f64::EPSILON);
164}
165
166#[test]
167fn check_construct_decimal() {
168 assert_decimal_value(&DecimalNumber::new(0.777), (1, 0.777));
169 assert_decimal_value(&DecimalNumber::new(-0.777), (-1, 0.777));
170 expect!([r"
171 DecimalNumber {
172 sign: 1,
173 value: 1.0,
174 }
175 "])
176 .assert_debug_eq(&DecimalNumber::new(1.0));
177}
178
179#[test]
180fn check_recognize_decimal() {
181 assert_decimal_value(&DecimalNumber::recognize(0.777), (1, 0.777));
182 assert_decimal_value(&DecimalNumber::recognize(-0.777), (-1, 0.777));
183}
184
185#[test]
186fn check_recognize_real_number() {
187 expect!([r"
188 Zero
189 "])
190 .assert_debug_eq(&RealNumber::recognize(0.0));
191
192 expect!([r"
193 Algebraic(
194 AlgebraicNumber {
195 sign: 1,
196 fraction: RationalNumber {
197 sign: 1,
198 numerator: 5,
199 denominator: 3,
200 },
201 root: 2,
202 },
203 )
204 "])
205 .assert_debug_eq(&RealNumber::recognize(5.0 * 2.0_f64.sqrt() / 3.0));
206
207 expect!([r"
208 Algebraic(
209 AlgebraicNumber {
210 sign: 1,
211 fraction: RationalNumber {
212 sign: 1,
213 numerator: 7,
214 denominator: 10,
215 },
216 root: 1,
217 },
218 )
219 "])
220 .assert_debug_eq(&RealNumber::recognize(7.0 / 10.0));
221
222 expect!([r"
223 Decimal(
224 DecimalNumber {
225 sign: 1,
226 value: 0.00558659217877095,
227 },
228 )
229 "])
230 .assert_debug_eq(&RealNumber::recognize(1.0 / 179.0));
231
232 expect!([r"
233 Algebraic(
234 AlgebraicNumber {
235 sign: -1,
236 fraction: RationalNumber {
237 sign: 1,
238 numerator: 2,
239 denominator: 3,
240 },
241 root: 1,
242 },
243 )
244 "])
245 .assert_debug_eq(&RealNumber::recognize(-2.0 / 3.0));
246
247 expect!([r"
248 Algebraic(
249 AlgebraicNumber {
250 sign: -1,
251 fraction: RationalNumber {
252 sign: 1,
253 numerator: 5,
254 denominator: 7,
255 },
256 root: 3,
257 },
258 )
259 "])
260 .assert_debug_eq(&RealNumber::recognize(-5.0 * 3.0_f64.sqrt() / 7.0));
261}
262
263#[test]
264fn check_recognize_polar() {
265 expect!([r"
266 Some(
267 PolarForm {
268 sign: 1,
269 magnitude: AlgebraicNumber {
270 sign: 1,
271 fraction: RationalNumber {
272 sign: 1,
273 numerator: 5,
274 denominator: 2,
275 },
276 root: 1,
277 },
278 phase_multiplier: RationalNumber {
279 sign: 1,
280 numerator: 1,
281 denominator: 3,
282 },
283 },
284 )
285 "])
286 .assert_debug_eq(&PolarForm::recognize(
287 5.0 / 2.0 * (PI / 3.0).cos(),
288 5.0 / 2.0 * (PI / 3.0).sin(),
289 ));
290 expect!([r"
291 Some(
292 PolarForm {
293 sign: 1,
294 magnitude: AlgebraicNumber {
295 sign: 1,
296 fraction: RationalNumber {
297 sign: 1,
298 numerator: 5,
299 denominator: 2,
300 },
301 root: 1,
302 },
303 phase_multiplier: RationalNumber {
304 sign: -1,
305 numerator: 1,
306 denominator: 3,
307 },
308 },
309 )
310 "])
311 .assert_debug_eq(&PolarForm::recognize(
312 5.0 / 2.0 * (PI / 3.0).cos(),
313 5.0 / 2.0 * (-PI / 3.0).sin(),
314 ));
315}
316
317#[test]
318fn check_recognize_cartesian() {
319 expect!([r"
320 CartesianForm {
321 sign: -1,
322 real_part: Zero,
323 imaginary_part: Algebraic(
324 AlgebraicNumber {
325 sign: 1,
326 fraction: RationalNumber {
327 sign: 1,
328 numerator: 5,
329 denominator: 3,
330 },
331 root: 2,
332 },
333 ),
334 }
335 "])
336 .assert_debug_eq(&CartesianForm::recognize(0.0, -5.0 / 3.0 * 2.0_f64.sqrt()));
337 expect!([r"
338 CartesianForm {
339 sign: -1,
340 real_part: Algebraic(
341 AlgebraicNumber {
342 sign: 1,
343 fraction: RationalNumber {
344 sign: 1,
345 numerator: 7,
346 denominator: 3,
347 },
348 root: 1,
349 },
350 ),
351 imaginary_part: Algebraic(
352 AlgebraicNumber {
353 sign: -1,
354 fraction: RationalNumber {
355 sign: 1,
356 numerator: 2,
357 denominator: 9,
358 },
359 root: 3,
360 },
361 ),
362 }
363 "])
364 .assert_debug_eq(&CartesianForm::recognize(
365 -7.0 / 3.0,
366 2.0 / 9.0 * 3.0_f64.sqrt(),
367 ));
368}
369
370#[test]
371fn check_recognize_complex() {
372 expect!([r"
373 Cartesian(
374 CartesianForm {
375 sign: -1,
376 real_part: Zero,
377 imaginary_part: Algebraic(
378 AlgebraicNumber {
379 sign: 1,
380 fraction: RationalNumber {
381 sign: 1,
382 numerator: 5,
383 denominator: 3,
384 },
385 root: 2,
386 },
387 ),
388 },
389 )
390 "])
391 .assert_debug_eq(&ComplexNumber::recognize(0.0, -5.0 / 3.0 * 2.0_f64.sqrt()));
392
393 expect!([r"
394 Cartesian(
395 CartesianForm {
396 sign: -1,
397 real_part: Algebraic(
398 AlgebraicNumber {
399 sign: 1,
400 fraction: RationalNumber {
401 sign: 1,
402 numerator: 7,
403 denominator: 3,
404 },
405 root: 1,
406 },
407 ),
408 imaginary_part: Algebraic(
409 AlgebraicNumber {
410 sign: -1,
411 fraction: RationalNumber {
412 sign: 1,
413 numerator: 2,
414 denominator: 9,
415 },
416 root: 3,
417 },
418 ),
419 },
420 )
421 "])
422 .assert_debug_eq(&ComplexNumber::recognize(
423 -7.0 / 3.0,
424 2.0 / 9.0 * 3.0_f64.sqrt(),
425 ));
426
427 expect!([r"
428 Polar(
429 PolarForm {
430 sign: 1,
431 magnitude: AlgebraicNumber {
432 sign: 1,
433 fraction: RationalNumber {
434 sign: 1,
435 numerator: 5,
436 denominator: 2,
437 },
438 root: 1,
439 },
440 phase_multiplier: RationalNumber {
441 sign: 1,
442 numerator: 1,
443 denominator: 3,
444 },
445 },
446 )
447 "])
448 .assert_debug_eq(&ComplexNumber::recognize(
449 5.0 / 2.0 * (PI / 3.0).cos(),
450 5.0 / 2.0 * (PI / 3.0).sin(),
451 ));
452}
453
454fn assert_latex_for_algebraic(
455 expected: &Expect,
456 numerator: i64,
457 denominator: i64,
458 root: i64,
459 render_one: bool,
460) {
461 let number = AlgebraicNumber::new(&RationalNumber::new(numerator, denominator), root);
462 let mut latex = String::with_capacity(50);
463 write_latex_for_algebraic_number(&mut latex, &number, render_one);
464 expected.assert_eq(&latex);
465}
466
467#[test]
468fn check_get_latex_for_algebraic() {
469 assert_latex_for_algebraic(&expect!([r"\frac{5 \sqrt{2}}{3}"]), 5, 3, 2, false);
470 assert_latex_for_algebraic(&expect!([r"\frac{5 \sqrt{2}}{3}"]), -5, 3, 2, false);
471 assert_latex_for_algebraic(&expect!([r"\frac{\sqrt{2}}{3}"]), 1, 3, 2, false);
472 assert_latex_for_algebraic(&expect!([r"5 \sqrt{2}"]), 5, 1, 2, false);
473 assert_latex_for_algebraic(&expect!([r"\frac{5}{3}"]), 5, 3, 1, false);
474 assert_latex_for_algebraic(&expect!([r"\sqrt{2}"]), 1, 1, 2, false);
475 assert_latex_for_algebraic(&expect!("5"), 5, 1, 1, false);
476 assert_latex_for_algebraic(&expect!([r"\frac{1}{3}"]), 1, 3, 1, false);
477 assert_latex_for_algebraic(&expect!(""), 1, 1, 1, false);
478 assert_latex_for_algebraic(&expect!("1"), 1, 1, 1, true);
479}
480
481fn assert_latex_for_decimal(expected: &Expect, number: f64, render_one: bool) {
482 let number = DecimalNumber::new(number);
483 let mut latex = String::with_capacity(50);
484 write_latex_for_decimal_number(&mut latex, &number, render_one);
485 expected.assert_eq(&latex);
486}
487
488#[test]
489fn check_get_latex_for_decimal() {
490 assert_latex_for_decimal(&expect!("0.25"), 0.25, false);
491 assert_latex_for_decimal(&expect!("0.25"), -0.25, false);
492 assert_latex_for_decimal(&expect!(""), -1.0, false);
493 assert_latex_for_decimal(&expect!(""), 1.0, false);
494 assert_latex_for_decimal(&expect!("1"), 1.0, true);
495}
496
497fn assert_latex_for_real(expected: &Expect, x: f64, render_one: bool) {
498 let number = RealNumber::recognize(x);
499 let mut latex = String::with_capacity(50);
500 write_latex_for_real_number(&mut latex, &number, render_one);
501 expected.assert_eq(&latex);
502}
503
504#[test]
505fn check_get_latex_for_real() {
506 assert_latex_for_real(&expect!([r"\frac{1}{4}"]), 1.0 / 4.0, false);
507 assert_latex_for_real(&expect!([r"\frac{1}{4}"]), -1.0 / 4.0, false);
508 assert_latex_for_real(&expect!(""), 1.0, false);
509 assert_latex_for_real(&expect!("1"), 1.0, true);
510 assert_latex_for_real(&expect!("0"), 0.0, false);
511 assert_latex_for_real(&expect!("0.0003"), 1.0 / 4000.0, false);
512}
513
514fn assert_latex_for_cartesian(expected: &Expect, re: f64, im: f64, render_plus: bool) {
515 let number = CartesianForm::recognize(re, im);
516 let mut latex = String::with_capacity(50);
517 write_latex_for_cartesian_form(&mut latex, &number, render_plus, false);
518 expected.assert_eq(&latex);
519}
520
521#[test]
522fn check_get_latex_for_cartesian() {
523 assert_latex_for_cartesian(
524 &expect!([r"\left( \frac{1}{2}+\frac{1}{2}i \right)"]),
525 0.5,
526 0.5,
527 false,
528 );
529 assert_latex_for_cartesian(
530 &expect!([r"-\left( \frac{1}{2}-\frac{1}{2}i \right)"]),
531 -0.5,
532 0.5,
533 false,
534 );
535 assert_latex_for_cartesian(
536 &expect!([r"\left( \frac{1}{2}-\frac{1}{2}i \right)"]),
537 0.5,
538 -0.5,
539 false,
540 );
541 assert_latex_for_cartesian(
542 &expect!([r"-\left( \frac{1}{2}+\frac{1}{2}i \right)"]),
543 -0.5,
544 -0.5,
545 false,
546 );
547 assert_latex_for_cartesian(&expect!([r"-\frac{1}{2}i"]), 0.0, -0.5, false);
548 assert_latex_for_cartesian(&expect!([r"-\frac{1}{2}"]), -0.5, 0.0, false);
549 assert_latex_for_cartesian(&expect!(""), 1.0, 0.0, false);
550 assert_latex_for_cartesian(&expect!("+"), 1.0, 0.0, true);
551}
552
553fn assert_latex_for_polar(expected: &Expect, re: f64, im: f64, render_plus: bool) {
554 let number = PolarForm::recognize(re, im).expect("Polar form not recognized.");
555 let mut latex = String::with_capacity(50);
556 write_latex_for_polar_form(&mut latex, &number, render_plus);
557 expected.assert_eq(&latex);
558}
559
560#[test]
561fn check_get_latex_for_polar() {
562 assert_latex_for_polar(
563 &expect!([r"+\frac{1}{2} e^{ i \pi / 3}"]),
564 1.0 / 2.0 * (PI / 3.0).cos(),
565 1.0 / 2.0 * (PI / 3.0).sin(),
566 true,
567 );
568 assert_latex_for_polar(
569 &expect!([r"+ e^{ i \pi / 3}"]),
570 (PI / 3.0).cos(),
571 (PI / 3.0).sin(),
572 true,
573 );
574 assert_latex_for_polar(
575 &expect!([r"+\frac{1}{2} e^{- i \pi / 3}"]),
576 1.0 / 2.0 * (-PI / 3.0).cos(),
577 1.0 / 2.0 * (-PI / 3.0).sin(),
578 true,
579 );
580 assert_latex_for_polar(
581 &expect!([r"+\frac{1}{2} e^{2 i \pi / 3}"]),
582 1.0 / 2.0 * (2.0 * PI / 3.0).cos(),
583 1.0 / 2.0 * (2.0 * PI / 3.0).sin(),
584 true,
585 );
586 assert_latex_for_polar(
587 &expect!([r"+\frac{1}{2} e^{-2 i \pi / 3}"]),
588 1.0 / 2.0 * (-2.0 * PI / 3.0).cos(),
589 1.0 / 2.0 * (-2.0 * PI / 3.0).sin(),
590 true,
591 );
592 assert_latex_for_polar(
593 &expect!([r"\frac{1}{2} e^{-2 i \pi / 3}"]),
594 1.0 / 2.0 * (-2.0 * PI / 3.0).cos(),
595 1.0 / 2.0 * (-2.0 * PI / 3.0).sin(),
596 false,
597 );
598}
599
600fn assert_latex_for_term(expected: &Expect, re: f64, im: f64, render_plus: bool) {
601 let t: Term = Term {
602 basis_vector: 0_u8.into(),
603 coordinate: ComplexNumber::recognize(re, im),
604 };
605 let mut latex = String::with_capacity(50);
606 write_latex_for_term(&mut latex, &t, render_plus);
607 expected.assert_eq(&latex);
608}
609
610#[test]
611fn check_get_latex_for_term() {
612 assert_latex_for_term(
613 &expect!([r"+\frac{1}{2} e^{ i \pi / 3}"]),
614 1.0 / 2.0 * (PI / 3.0).cos(),
615 1.0 / 2.0 * (PI / 3.0).sin(),
616 true,
617 );
618 assert_latex_for_term(
619 &expect!([r"+\left( \frac{1}{2}+\frac{1}{2}i \right)"]),
620 1.0 / 2.0,
621 1.0 / 2.0,
622 true,
623 );
624 assert_latex_for_term(
625 &expect!([r"\left( \frac{1}{2}+\frac{1}{2}i \right)"]),
626 1.0 / 2.0,
627 1.0 / 2.0,
628 false,
629 );
630 assert_latex_for_term(
631 &expect!([r"-\left( \frac{1}{2}-\frac{1}{2}i \right)"]),
632 -1.0 / 2.0,
633 1.0 / 2.0,
634 true,
635 );
636 assert_latex_for_term(
637 &expect!([r"-\left( \frac{1}{2}-\frac{1}{2}i \right)"]),
638 -1.0 / 2.0,
639 1.0 / 2.0,
640 false,
641 );
642}
643
644fn assert_latex_for_complex_number(expected: &Expect, re: f64, im: f64) {
645 let n: ComplexNumber = ComplexNumber::recognize(re, im);
646 let mut latex = String::with_capacity(50);
647 write_latex_for_complex_number(&mut latex, &n);
648 expected.assert_eq(&latex);
649}
650
651#[test]
652fn check_get_latex_for_complex_number() {
653 // Future work:
654 // While rendering is correct, a better way may be the following:
655 // -(1-i) -> -1+i remove brackets for standalone number
656 // 1/2 i -> i/2
657 // √2/2 -> 1/√2
658 assert_latex_for_complex_number(&expect!([r"0"]), 0.0, 0.0);
659
660 assert_latex_for_complex_number(&expect!([r"1"]), 1.0, 0.0);
661 assert_latex_for_complex_number(&expect!([r"-1"]), -1.0, 0.0);
662 assert_latex_for_complex_number(&expect!([r"i"]), 0.0, 1.0);
663 assert_latex_for_complex_number(&expect!([r"-i"]), 0.0, -1.0);
664
665 assert_latex_for_complex_number(&expect!([r"\frac{1}{2}"]), 0.5, 0.0);
666 assert_latex_for_complex_number(&expect!([r"-\frac{1}{2}"]), -0.5, 0.0);
667 assert_latex_for_complex_number(&expect!([r"\frac{1}{2}i"]), 0.0, 0.5);
668 assert_latex_for_complex_number(&expect!([r"-\frac{1}{2}i"]), 0.0, -0.5);
669
670 assert_latex_for_complex_number(
671 &expect!([r#"\left( \frac{1}{2}+\frac{1}{2}i \right)"#]),
672 0.5,
673 0.5,
674 );
675 assert_latex_for_complex_number(
676 &expect!([r#"-\left( \frac{1}{2}-\frac{1}{2}i \right)"#]),
677 -0.5,
678 0.5,
679 );
680 assert_latex_for_complex_number(
681 &expect!([r#"\left( \frac{1}{2}-\frac{1}{2}i \right)"#]),
682 0.5,
683 -0.5,
684 );
685 assert_latex_for_complex_number(
686 &expect!([r#"-\left( \frac{1}{2}+\frac{1}{2}i \right)"#]),
687 -0.5,
688 -0.5,
689 );
690
691 assert_latex_for_complex_number(&expect!([r#"\frac{\sqrt{2}}{2}"#]), FRAC_1_SQRT_2, 0.0);
692 assert_latex_for_complex_number(&expect!([r#"-\frac{\sqrt{2}}{2}"#]), -FRAC_1_SQRT_2, 0.0);
693 assert_latex_for_complex_number(&expect!([r#"\frac{\sqrt{2}}{2}i"#]), 0.0, FRAC_1_SQRT_2);
694 assert_latex_for_complex_number(&expect!([r#"-\frac{\sqrt{2}}{2}i"#]), 0.0, -FRAC_1_SQRT_2);
695
696 assert_latex_for_complex_number(
697 &expect!([r"\frac{1}{2} e^{ i \pi / 3}"]),
698 1.0 / 2.0 * (PI / 3.0).cos(),
699 1.0 / 2.0 * (PI / 3.0).sin(),
700 );
701 assert_latex_for_complex_number(
702 &expect!([r#"\left( \frac{1}{2}+\frac{1}{2}i \right)"#]),
703 1.0 / 2.0,
704 1.0 / 2.0,
705 );
706}
707
708#[test]
709fn check_get_latex() {
710 expect!([r"$|\psi\rangle = \left( \frac{1}{2}+\frac{1}{2}i \right)|00\rangle$"]).assert_eq(
711 &get_state_latex(&vec![(0_u8.into(), Complex64::new(0.5, 0.5))], 2)
712 .expect("expected valid latex"),
713 );
714 expect!([r"$|\psi\rangle = -|00\rangle$"]).assert_eq(
715 &get_state_latex(&vec![(0_u8.into(), Complex64::new(-1.0, 0.0))], 2)
716 .expect("expected valid latex"),
717 );
718 expect!([r"$|\psi\rangle = -i|00\rangle$"]).assert_eq(
719 &get_state_latex(&vec![(0_u8.into(), Complex64::new(0.0, -1.0))], 2)
720 .expect("expected valid latex"),
721 );
722 expect!([r"$|\psi\rangle = e^{-2 i \pi / 3}|00\rangle$"]).assert_eq(
723 &get_state_latex(
724 &vec![(
725 0_u8.into(),
726 Complex64::new((-2.0 * PI / 3.0).cos(), (-2.0 * PI / 3.0).sin()),
727 )],
728 2,
729 )
730 .expect("expected valid latex"),
731 );
732 expect!([r"$|\psi\rangle = \left( 1+\frac{\sqrt{2}}{2}i \right)|00\rangle+\left( 1+\frac{\sqrt{2}}{2}i \right)|10\rangle$"])
733 .assert_eq(&get_state_latex(
734 &vec![
735 (0_u8.into(), Complex64::new(1.0, 1.0 / 2.0_f64.sqrt())),
736 (2_u8.into(), Complex64::new(1.0, 1.0 / 2.0_f64.sqrt())),
737 ],
738 2,
739 ).expect("expected valid latex"));
740}
741
742#[test]
743fn check_get_matrix_latex() {
744 expect!([r#"$ \begin{bmatrix} 0 & 1 \\ i & \left( 1+i \right) \\ \end{bmatrix} $"#]).assert_eq(
745 &get_matrix_latex(&vec![
746 vec![Complex64::new(0.0, 0.0), Complex64::new(1.0, 0.0)],
747 vec![Complex64::new(0.0, 1.0), Complex64::new(1.0, 1.0)],
748 ]),
749 );
750 expect!([r#"$ \begin{bmatrix} -\left( 1-i \right) & -1 \\ -i & -\left( 1+i \right) \\ \end{bmatrix} $"#]).assert_eq(
751 &get_matrix_latex(&vec![
752 vec![Complex64::new(-1.0, 1.0), Complex64::new(-1.0, 0.0)],
753 vec![Complex64::new(0.0, -1.0), Complex64::new(-1.0, -1.0)],
754 ]),
755 );
756 expect!([r#"$ \begin{bmatrix} \frac{1}{\sqrt{2}} & \frac{i}{\sqrt{2}} \\ -\frac{1}{\sqrt{2}} & -\frac{i}{\sqrt{2}} \\ \end{bmatrix} $"#]).assert_eq(&get_matrix_latex(&vec![
757 vec![
758 Complex64::new(FRAC_1_SQRT_2, 0.0),
759 Complex64::new(0.0, FRAC_1_SQRT_2),
760 ],
761 vec![
762 Complex64::new(-FRAC_1_SQRT_2, 0.0),
763 Complex64::new(0.0, -FRAC_1_SQRT_2),
764 ],
765 ]));
766 expect!([r#"$ \begin{bmatrix} \frac{1}{2} & \frac{i}{2} \\ -\frac{1}{2} & -\frac{i}{2} \\ \end{bmatrix} $"#]).assert_eq(&get_matrix_latex(&vec![
767 vec![
768 Complex64::new(0.5, 0.0),
769 Complex64::new(0.0, 0.5),
770 ],
771 vec![
772 Complex64::new(-0.5, 0.0),
773 Complex64::new(0.0, -0.5),
774 ],
775 ]));
776 expect!([r#"$ \begin{bmatrix} \frac{1}{2} + \frac{i}{2} & -\frac{1}{2} - \frac{i}{2} \\ -\frac{1}{2} + \frac{i}{2} & \frac{1}{2} - \frac{i}{2} \\ \end{bmatrix} $"#]).assert_eq(&get_matrix_latex(&vec![
777 vec![
778 Complex64::new(0.5, 0.5),
779 Complex64::new(-0.5, -0.5),
780 ],
781 vec![
782 Complex64::new(-0.5, 0.5),
783 Complex64::new(0.5, -0.5),
784 ],
785 ]));
786}
787
788#[test]
789fn check_get_latex_perf() {
790 // This is not a CI gate for performance, just prints out data.
791 let state = vec![
792 (0_u8.into(), Complex64::new(1.0 / 2.0, 0.0)),
793 (
794 1_u8.into(),
795 Complex64::new(0.353_553_390_593_273_8, 0.353_553_390_593_273_8),
796 ),
797 (2_u8.into(), Complex64::new(0.0, 1.0 / 2.0)),
798 (
799 3_u8.into(),
800 Complex64::new(-0.353_553_390_593_273_8, 0.353_553_390_593_273_8),
801 ),
802 ];
803
804 expect!([r"$|\psi\rangle = \frac{1}{2}|00\rangle+\frac{1}{2} e^{ i \pi / 4}|01\rangle+\frac{1}{2}i|10\rangle+\frac{1}{2} e^{3 i \pi / 4}|11\rangle$"])
805 .assert_eq(&get_state_latex(
806 &state,
807 2,
808 ).expect("expected valid latex"));
809
810 print!("Start...");
811 let start = Instant::now();
812 let mut l: usize = 0;
813 for _ in 0..1_000 {
814 let s = get_state_latex(&state, 2);
815 l += s.map_or(0, |s| s.len());
816 }
817 println!(
818 "Done. {} bytes in {:?}.",
819 l,
820 Instant::now().duration_since(start)
821 );
822}
823