microsoft/qdk

Public

mirrored fromhttps://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
f9ff1026ee0d8ead8c9892e7ca362a90fb72042a

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc_eval/src/state/tests.rs

820lines · modecode

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