1use klu_sys::{
2 klu_analyze, klu_defaults, klu_factor, klu_free_numeric, klu_free_symbolic, klu_l_analyze,
3 klu_l_defaults, klu_l_factor, klu_l_free_numeric, klu_l_free_symbolic, klu_l_rcond,
4 klu_l_refactor, klu_l_solve, klu_l_tsolve, klu_rcond, klu_refactor, klu_solve, klu_tsolve,
5 klu_z_factor, klu_z_free_numeric, klu_z_rcond, klu_z_refactor, klu_z_solve, klu_z_tsolve,
6 klu_zl_factor, klu_zl_free_numeric, klu_zl_rcond, klu_zl_refactor, klu_zl_solve, klu_zl_tsolve,
7 KluCommon, KluLCommon, KluLNumeric, KluLSymbolic, KluNumeric, KluSymbolic,
8};
9use num_complex::{Complex64, ComplexFloat};
10
11use crate::raw::sealed::Sealed;
12use std::fmt::Debug;
13use std::ops::{Add, AddAssign, Div, Mul, Sub};
14
15mod sealed {
16 use num_complex::Complex64;
17
18 pub trait Sealed {}
19 impl Sealed for f64 {}
20 impl Sealed for Complex64 {}
21 impl Sealed for i32 {}
22 impl Sealed for i64 {}
23}
24
25#[allow(clippy::missing_safety_doc)]
28pub trait KluData:
29 Sealed
30 + Copy
31 + PartialEq
32 + Debug
33 + Default
34 + Mul
35 + Sub
36 + Add
37 + AddAssign
38 + Div
39 + ComplexFloat<Real = f64>
40 + 'static
41{
42 unsafe fn klu_solve<I: KluIndex>(
43 symbolic: *mut I::KluSymbolic,
44 numeric: *mut I::KluNumeric,
45 rhs_dimension: I,
46 number_rhs: I,
47 rhs_data: *mut Self,
48 common: *mut I::KluCommon,
49 ) -> bool;
50
51 unsafe fn klu_tsolve<I: KluIndex>(
52 symbolic: *mut I::KluSymbolic,
53 numeric: *mut I::KluNumeric,
54 rhs_dimension: I,
55 number_rhs: I,
56 rhs_data: *mut Self,
57 common: *mut I::KluCommon,
58 ) -> bool;
59
60 unsafe fn klu_factor<I: KluIndex>(
61 colum_offsets: *const I,
62 row_indices: *const I,
63 data: *mut Self,
64 symbolic: *mut I::KluSymbolic,
65 common: *mut I::KluCommon,
66 ) -> *mut I::KluNumeric;
67
68 unsafe fn klu_refactor<I: KluIndex>(
69 colum_offsets: *const I,
70 row_indices: *const I,
71 data: *mut Self,
72 symbolic: *mut I::KluSymbolic,
73 numeric: *mut I::KluNumeric,
74 common: *mut I::KluCommon,
75 ) -> bool;
76
77 unsafe fn klu_free_numeric<I: KluIndex>(
78 numeric: *mut *mut I::KluNumeric,
79 common: *mut I::KluCommon,
80 );
81
82 unsafe fn klu_rcond<I: KluIndex>(
83 symbolic: *mut I::KluSymbolic,
84 numeric: *mut I::KluNumeric,
85 common: *mut I::KluCommon,
86 ) -> bool;
87}
88
89#[allow(clippy::missing_safety_doc)]
92pub trait KluIndex:
93 PartialEq + PartialOrd + Ord + Debug + Copy + Clone + Eq + Sealed + Add<Output = Self>
94{
95 type KluCommon: Debug;
96 type KluNumeric: Debug;
97 type KluSymbolic: Debug;
98
99 fn from_usize(val: usize) -> Self;
100 fn into_usize(self) -> usize;
101
102 unsafe fn klu_defaults(common: *mut Self::KluCommon) -> Self;
103
104 unsafe fn klu_analyze(
105 dim: Self,
106 colum_offsets: *const Self,
107 row_indices: *const Self,
108 common: *mut Self::KluCommon,
109 ) -> *mut Self::KluSymbolic;
110
111 unsafe fn klu_free_symbolic(
112 symbolic: *mut *mut Self::KluSymbolic,
113 common: *mut Self::KluCommon,
114 );
115
116 unsafe fn klu_factor(
117 colum_offsets: *const Self,
118 row_indices: *const Self,
119 data: *mut f64,
120 symbolic: *mut Self::KluSymbolic,
121 common: *mut Self::KluCommon,
122 ) -> *mut Self::KluNumeric;
123
124 unsafe fn klu_z_factor(
125 colum_offsets: *const Self,
126 row_indices: *const Self,
127 data: *mut f64,
128 symbolic: *mut Self::KluSymbolic,
129 common: *mut Self::KluCommon,
130 ) -> *mut Self::KluNumeric;
131
132 unsafe fn klu_refactor(
133 colum_offsets: *const Self,
134 row_indices: *const Self,
135 data: *mut f64,
136 symbolic: *mut Self::KluSymbolic,
137 numeric: *mut Self::KluNumeric,
138 common: *mut Self::KluCommon,
139 ) -> bool;
140
141 unsafe fn klu_z_refactor(
142 colum_offsets: *const Self,
143 row_indices: *const Self,
144 data: *mut f64,
145 symbolic: *mut Self::KluSymbolic,
146 numeric: *mut Self::KluNumeric,
147 common: *mut Self::KluCommon,
148 ) -> bool;
149
150 unsafe fn klu_solve(
151 symbolic: *mut Self::KluSymbolic,
152 numeric: *mut Self::KluNumeric,
153 rhs_dimension: Self,
154 number_rhs: Self,
155 rhs_data: *mut f64,
156 common: *mut Self::KluCommon,
157 ) -> bool;
158
159 unsafe fn klu_tsolve(
160 symbolic: *mut Self::KluSymbolic,
161 numeric: *mut Self::KluNumeric,
162 rhs_dimension: Self,
163 number_rhs: Self,
164 rhs_data: *mut f64,
165 common: *mut Self::KluCommon,
166 ) -> bool;
167
168 unsafe fn klu_z_solve(
169 symbolic: *mut Self::KluSymbolic,
170 numeric: *mut Self::KluNumeric,
171 rhs_dimension: Self,
172 number_rhs: Self,
173 rhs_data: *mut f64,
174 common: *mut Self::KluCommon,
175 ) -> bool;
176
177 unsafe fn klu_z_tsolve(
178 symbolic: *mut Self::KluSymbolic,
179 numeric: *mut Self::KluNumeric,
180 rhs_dimension: Self,
181 number_rhs: Self,
182 rhs_data: *mut f64,
183 common: *mut Self::KluCommon,
184 ) -> bool;
185
186 unsafe fn klu_free_numeric(numeric: *mut *mut Self::KluNumeric, common: *mut Self::KluCommon);
187
188 unsafe fn klu_z_free_numeric(numeric: *mut *mut Self::KluNumeric, common: *mut Self::KluCommon);
189
190 fn check_status(common: &Self::KluCommon);
191 fn get_rcond(common: &Self::KluCommon) -> f64;
192 fn is_singular(common: &Self::KluCommon) -> bool;
193
194 unsafe fn klu_rcond(
195 symbolic: *mut Self::KluSymbolic,
196 numeric: *mut Self::KluNumeric,
197 common: *mut Self::KluCommon,
198 ) -> bool;
199
200 unsafe fn klu_z_rcond(
201 symbolic: *mut Self::KluSymbolic,
202 numeric: *mut Self::KluNumeric,
203 common: *mut Self::KluCommon,
204 ) -> bool;
205}
206
207impl KluData for f64 {
208 unsafe fn klu_solve<I: KluIndex>(
209 symbolic: *mut <I as KluIndex>::KluSymbolic,
210 numeric: *mut <I as KluIndex>::KluNumeric,
211 rhs_dimension: I,
212 number_rhs: I,
213 rhs_data: *mut Self,
214 common: *mut <I as KluIndex>::KluCommon,
215 ) -> bool {
216 I::klu_solve(
217 symbolic,
218 numeric,
219 rhs_dimension,
220 number_rhs,
221 rhs_data,
222 common,
223 )
224 }
225
226 unsafe fn klu_tsolve<I: KluIndex>(
227 symbolic: *mut I::KluSymbolic,
228 numeric: *mut I::KluNumeric,
229 rhs_dimension: I,
230 number_rhs: I,
231 rhs_data: *mut Self,
232 common: *mut I::KluCommon,
233 ) -> bool {
234 I::klu_tsolve(
235 symbolic,
236 numeric,
237 rhs_dimension,
238 number_rhs,
239 rhs_data,
240 common,
241 )
242 }
243
244 unsafe fn klu_factor<I: KluIndex>(
245 colum_offsets: *const I,
246 row_indices: *const I,
247 data: *mut Self,
248 symbolic: *mut I::KluSymbolic,
249 common: *mut I::KluCommon,
250 ) -> *mut I::KluNumeric {
251 I::klu_factor(colum_offsets, row_indices, data, symbolic, common)
252 }
253
254 unsafe fn klu_refactor<I: KluIndex>(
255 colum_offsets: *const I,
256 row_indices: *const I,
257 data: *mut Self,
258 symbolic: *mut I::KluSymbolic,
259 numeric: *mut I::KluNumeric,
260 common: *mut I::KluCommon,
261 ) -> bool {
262 I::klu_refactor(colum_offsets, row_indices, data, symbolic, numeric, common)
263 }
264
265 unsafe fn klu_free_numeric<I: KluIndex>(
266 numeric: *mut *mut I::KluNumeric,
267 common: *mut I::KluCommon,
268 ) {
269 I::klu_free_numeric(numeric, common)
270 }
271
272 unsafe fn klu_rcond<I: KluIndex>(
273 symbolic: *mut I::KluSymbolic,
274 numeric: *mut I::KluNumeric,
275 common: *mut I::KluCommon,
276 ) -> bool {
277 I::klu_rcond(symbolic, numeric, common)
278 }
279}
280
281impl KluData for Complex64 {
282 unsafe fn klu_solve<I: KluIndex>(
283 symbolic: *mut <I as KluIndex>::KluSymbolic,
284 numeric: *mut <I as KluIndex>::KluNumeric,
285 rhs_dimension: I,
286 number_rhs: I,
287 rhs_data: *mut Self,
288 common: *mut <I as KluIndex>::KluCommon,
289 ) -> bool {
290 I::klu_z_solve(
291 symbolic,
292 numeric,
293 rhs_dimension,
294 number_rhs,
295 rhs_data as *mut f64,
296 common,
297 )
298 }
299
300 unsafe fn klu_tsolve<I: KluIndex>(
301 symbolic: *mut I::KluSymbolic,
302 numeric: *mut I::KluNumeric,
303 rhs_dimension: I,
304 number_rhs: I,
305 rhs_data: *mut Self,
306 common: *mut I::KluCommon,
307 ) -> bool {
308 I::klu_z_tsolve(
309 symbolic,
310 numeric,
311 rhs_dimension,
312 number_rhs,
313 rhs_data as *mut f64,
314 common,
315 )
316 }
317
318 unsafe fn klu_factor<I: KluIndex>(
319 colum_offsets: *const I,
320 row_indices: *const I,
321 data: *mut Self,
322 symbolic: *mut I::KluSymbolic,
323 common: *mut I::KluCommon,
324 ) -> *mut I::KluNumeric {
325 I::klu_z_factor(
326 colum_offsets,
327 row_indices,
328 data as *mut f64,
329 symbolic,
330 common,
331 )
332 }
333
334 unsafe fn klu_refactor<I: KluIndex>(
335 colum_offsets: *const I,
336 row_indices: *const I,
337 data: *mut Self,
338 symbolic: *mut I::KluSymbolic,
339 numeric: *mut I::KluNumeric,
340 common: *mut I::KluCommon,
341 ) -> bool {
342 I::klu_z_refactor(
343 colum_offsets,
344 row_indices,
345 data as *mut f64,
346 symbolic,
347 numeric,
348 common,
349 )
350 }
351
352 unsafe fn klu_free_numeric<I: KluIndex>(
353 numeric: *mut *mut I::KluNumeric,
354 common: *mut I::KluCommon,
355 ) {
356 I::klu_z_free_numeric(numeric, common)
357 }
358
359 unsafe fn klu_rcond<I: KluIndex>(
360 symbolic: *mut I::KluSymbolic,
361 numeric: *mut I::KluNumeric,
362 common: *mut I::KluCommon,
363 ) -> bool {
364 I::klu_z_rcond(symbolic, numeric, common)
365 }
366}
367impl KluIndex for i32 {
369 type KluCommon = KluCommon;
370 type KluNumeric = KluNumeric;
371 type KluSymbolic = KluSymbolic;
372
373 fn from_usize(val: usize) -> Self {
374 debug_assert!(val <= Self::MAX as usize);
375 val as Self
376 }
377
378 fn into_usize(self) -> usize {
379 debug_assert!(self >= 0);
380 self as usize
381 }
382
383 unsafe fn klu_defaults(common: *mut Self::KluCommon) -> Self {
384 klu_defaults(common)
385 }
386
387 unsafe fn klu_analyze(
388 dim: Self,
389 colum_offsets: *const Self,
390 row_indices: *const Self,
391 common: *mut Self::KluCommon,
392 ) -> *mut Self::KluSymbolic {
393 klu_analyze(
394 dim,
395 colum_offsets as *mut Self,
396 row_indices as *mut Self,
397 common,
398 )
399 }
400
401 unsafe fn klu_free_symbolic(
402 symbolic: *mut *mut Self::KluSymbolic,
403 common: *mut Self::KluCommon,
404 ) {
405 if klu_free_symbolic(symbolic, common) == 0 {
406 unreachable!("freeing klu symbolic object failed")
407 }
408 }
409
410 unsafe fn klu_factor(
411 colum_offsets: *const Self,
412 row_indices: *const Self,
413 data: *mut f64,
414 symbolic: *mut Self::KluSymbolic,
415 common: *mut Self::KluCommon,
416 ) -> *mut Self::KluNumeric {
417 klu_factor(
418 colum_offsets as *mut Self,
419 row_indices as *mut Self,
420 data,
421 symbolic,
422 common,
423 )
424 }
425
426 unsafe fn klu_z_factor(
427 colum_offsets: *const Self,
428 row_indices: *const Self,
429 data: *mut f64,
430 symbolic: *mut Self::KluSymbolic,
431 common: *mut Self::KluCommon,
432 ) -> *mut Self::KluNumeric {
433 klu_z_factor(
434 colum_offsets as *mut Self,
435 row_indices as *mut Self,
436 data,
437 symbolic,
438 common,
439 )
440 }
441
442 unsafe fn klu_refactor(
443 colum_offsets: *const Self,
444 row_indices: *const Self,
445 data: *mut f64,
446 symbolic: *mut Self::KluSymbolic,
447 numeric: *mut Self::KluNumeric,
448 common: *mut Self::KluCommon,
449 ) -> bool {
450 klu_refactor(
451 colum_offsets as *mut Self,
452 row_indices as *mut Self,
453 data,
454 symbolic,
455 numeric,
456 common,
457 ) != 0
458 }
459
460 unsafe fn klu_z_refactor(
461 colum_offsets: *const Self,
462 row_indices: *const Self,
463 data: *mut f64,
464 symbolic: *mut Self::KluSymbolic,
465 numeric: *mut Self::KluNumeric,
466 common: *mut Self::KluCommon,
467 ) -> bool {
468 klu_z_refactor(
469 colum_offsets as *mut Self,
470 row_indices as *mut Self,
471 data,
472 symbolic,
473 numeric,
474 common,
475 ) != 0
476 }
477
478 unsafe fn klu_solve(
479 symbolic: *mut Self::KluSymbolic,
480 numeric: *mut Self::KluNumeric,
481 rhs_dimension: Self,
482 number_rhs: Self,
483 rhs_data: *mut f64,
484 common: *mut Self::KluCommon,
485 ) -> bool {
486 klu_solve(
487 symbolic,
488 numeric,
489 rhs_dimension,
490 number_rhs,
491 rhs_data,
492 common,
493 ) != 0
494 }
495
496 unsafe fn klu_tsolve(
497 symbolic: *mut Self::KluSymbolic,
498 numeric: *mut Self::KluNumeric,
499 rhs_dimension: Self,
500 number_rhs: Self,
501 rhs_data: *mut f64,
502 common: *mut Self::KluCommon,
503 ) -> bool {
504 klu_tsolve(
505 symbolic,
506 numeric,
507 rhs_dimension,
508 number_rhs,
509 rhs_data,
510 common,
511 ) != 0
512 }
513
514 unsafe fn klu_z_solve(
515 symbolic: *mut Self::KluSymbolic,
516 numeric: *mut Self::KluNumeric,
517 rhs_dimension: Self,
518 number_rhs: Self,
519 rhs_data: *mut f64,
520 common: *mut Self::KluCommon,
521 ) -> bool {
522 klu_z_solve(
523 symbolic,
524 numeric,
525 rhs_dimension,
526 number_rhs,
527 rhs_data,
528 common,
529 ) != 0
530 }
531
532 unsafe fn klu_z_tsolve(
533 symbolic: *mut Self::KluSymbolic,
534 numeric: *mut Self::KluNumeric,
535 rhs_dimension: Self,
536 number_rhs: Self,
537 rhs_data: *mut f64,
538 common: *mut Self::KluCommon,
539 ) -> bool {
540 klu_z_tsolve(
541 symbolic,
542 numeric,
543 rhs_dimension,
544 number_rhs,
545 rhs_data,
546 0,
547 common,
548 ) != 0
549 }
550
551 unsafe fn klu_free_numeric(numeric: *mut *mut Self::KluNumeric, common: *mut Self::KluCommon) {
552 if klu_free_numeric(numeric, common) == 0 {
553 unreachable!("freeing klu numeric object failed")
554 }
555 }
556
557 unsafe fn klu_z_free_numeric(
558 numeric: *mut *mut Self::KluNumeric,
559 common: *mut Self::KluCommon,
560 ) {
561 if klu_z_free_numeric(numeric, common) == 0 {
562 unreachable!("freeing klu numeric object failed")
563 }
564 }
565
566 fn check_status(common: &Self::KluCommon) {
567 match common.status {
568 -2 => unreachable!("KLU error: OUT OF MEMORY"),
569 -3 => unreachable!("KLU error: INVALID"),
570 -4 => unreachable!("KLU error: TOO LARGE"),
571 code @ (Self::MIN..=-5 | -1) => {
572 unreachable!("KLU failed with unkown errorcode {}", code)
573 }
574 _ => (),
575 }
576 }
577
578 fn get_rcond(common: &Self::KluCommon) -> f64 {
579 common.rcond
580 }
581
582 fn is_singular(common: &Self::KluCommon) -> bool {
583 common.status == 1
584 }
585
586 unsafe fn klu_rcond(
587 symbolic: *mut Self::KluSymbolic,
588 numeric: *mut Self::KluNumeric,
589 common: *mut Self::KluCommon,
590 ) -> bool {
591 klu_rcond(symbolic, numeric, common) != 0
592 }
593
594 unsafe fn klu_z_rcond(
595 symbolic: *mut Self::KluSymbolic,
596 numeric: *mut Self::KluNumeric,
597 common: *mut Self::KluCommon,
598 ) -> bool {
599 klu_z_rcond(symbolic, numeric, common) != 0
600 }
601}
602
603impl KluIndex for i64 {
605 type KluCommon = KluLCommon;
606 type KluNumeric = KluLNumeric;
607 type KluSymbolic = KluLSymbolic;
608
609 fn from_usize(val: usize) -> Self {
610 debug_assert!(val < Self::MAX as usize);
611 val as Self
612 }
613
614 fn into_usize(self) -> usize {
615 debug_assert!(self > 0);
616 self as usize
617 }
618
619 unsafe fn klu_defaults(common: *mut Self::KluCommon) -> Self {
620 klu_l_defaults(common)
621 }
622
623 unsafe fn klu_analyze(
624 dim: Self,
625 colum_offsets: *const Self,
626 row_indices: *const Self,
627 common: *mut Self::KluCommon,
628 ) -> *mut Self::KluSymbolic {
629 klu_l_analyze(
630 dim,
631 colum_offsets as *mut Self,
632 row_indices as *mut Self,
633 common,
634 )
635 }
636
637 unsafe fn klu_free_symbolic(
638 symbolic: *mut *mut Self::KluSymbolic,
639 common: *mut Self::KluCommon,
640 ) {
641 if klu_l_free_symbolic(symbolic, common) == 0 {
642 unreachable!("freeing klu numeric object failed")
643 }
644 }
645
646 unsafe fn klu_factor(
647 colum_offsets: *const Self,
648 row_indices: *const Self,
649 data: *mut f64,
650 symbolic: *mut Self::KluSymbolic,
651 common: *mut Self::KluCommon,
652 ) -> *mut Self::KluNumeric {
653 klu_l_factor(
654 colum_offsets as *mut Self,
655 row_indices as *mut Self,
656 data,
657 symbolic,
658 common,
659 )
660 }
661
662 unsafe fn klu_z_factor(
663 colum_offsets: *const Self,
664 row_indices: *const Self,
665 data: *mut f64,
666 symbolic: *mut Self::KluSymbolic,
667 common: *mut Self::KluCommon,
668 ) -> *mut Self::KluNumeric {
669 klu_zl_factor(
670 colum_offsets as *mut Self,
671 row_indices as *mut Self,
672 data,
673 symbolic,
674 common,
675 )
676 }
677
678 unsafe fn klu_refactor(
679 colum_offsets: *const Self,
680 row_indices: *const Self,
681 data: *mut f64,
682 symbolic: *mut Self::KluSymbolic,
683 numeric: *mut Self::KluNumeric,
684 common: *mut Self::KluCommon,
685 ) -> bool {
686 klu_l_refactor(
687 colum_offsets as *mut Self,
688 row_indices as *mut Self,
689 data,
690 symbolic,
691 numeric,
692 common,
693 ) != 0
694 }
695
696 unsafe fn klu_z_refactor(
697 colum_offsets: *const Self,
698 row_indices: *const Self,
699 data: *mut f64,
700 symbolic: *mut Self::KluSymbolic,
701 numeric: *mut Self::KluNumeric,
702 common: *mut Self::KluCommon,
703 ) -> bool {
704 klu_zl_refactor(
705 colum_offsets as *mut Self,
706 row_indices as *mut Self,
707 data,
708 symbolic,
709 numeric,
710 common,
711 ) != 0
712 }
713
714 unsafe fn klu_solve(
715 symbolic: *mut Self::KluSymbolic,
716 numeric: *mut Self::KluNumeric,
717 rhs_dimension: Self,
718 number_rhs: Self,
719 rhs_data: *mut f64,
720 common: *mut Self::KluCommon,
721 ) -> bool {
722 klu_l_solve(
723 symbolic,
724 numeric,
725 rhs_dimension,
726 number_rhs,
727 rhs_data,
728 common,
729 ) != 0
730 }
731
732 unsafe fn klu_tsolve(
733 symbolic: *mut Self::KluSymbolic,
734 numeric: *mut Self::KluNumeric,
735 rhs_dimension: Self,
736 number_rhs: Self,
737 rhs_data: *mut f64,
738 common: *mut Self::KluCommon,
739 ) -> bool {
740 klu_l_tsolve(
741 symbolic,
742 numeric,
743 rhs_dimension,
744 number_rhs,
745 rhs_data,
746 common,
747 ) != 0
748 }
749
750 unsafe fn klu_z_solve(
751 symbolic: *mut Self::KluSymbolic,
752 numeric: *mut Self::KluNumeric,
753 rhs_dimension: Self,
754 number_rhs: Self,
755 rhs_data: *mut f64,
756 common: *mut Self::KluCommon,
757 ) -> bool {
758 klu_zl_solve(
759 symbolic,
760 numeric,
761 rhs_dimension,
762 number_rhs,
763 rhs_data,
764 common,
765 ) != 0
766 }
767
768 unsafe fn klu_z_tsolve(
769 symbolic: *mut Self::KluSymbolic,
770 numeric: *mut Self::KluNumeric,
771 rhs_dimension: Self,
772 number_rhs: Self,
773 rhs_data: *mut f64,
774 common: *mut Self::KluCommon,
775 ) -> bool {
776 klu_zl_tsolve(
777 symbolic,
778 numeric,
779 rhs_dimension,
780 number_rhs,
781 rhs_data,
782 0,
783 common,
784 ) != 0
785 }
786
787 unsafe fn klu_free_numeric(numeric: *mut *mut Self::KluNumeric, common: *mut Self::KluCommon) {
788 if klu_l_free_numeric(numeric, common) == 0 {
789 unreachable!("freeing klu numeric object failed")
790 }
791 }
792
793 unsafe fn klu_z_free_numeric(
794 numeric: *mut *mut Self::KluNumeric,
795 common: *mut Self::KluCommon,
796 ) {
797 if klu_zl_free_numeric(numeric, common) == 0 {
798 unreachable!("freeing klu numeric object failed")
799 }
800 }
801
802 fn check_status(common: &Self::KluCommon) {
803 match common.status {
804 0 => (),
805 -1 => unreachable!("KLU failed with unkown errorcode -1"),
806 -2 => unreachable!("KLU error: OUT OF MEMORY"),
807 -3 => unreachable!("KLU error: INVALID"),
808 -4 => unreachable!("KLU error: TOO LARGE"),
809 code @ Self::MIN..=-5 => unreachable!("KLU failed with unkown errorcode {}", code),
810 1 => unreachable!("Singular matrix!"),
811 code => unreachable!("Unkown warning {code}"),
812 }
813 }
814
815 fn get_rcond(common: &Self::KluCommon) -> f64 {
816 common.rcond
817 }
818
819 fn is_singular(common: &Self::KluCommon) -> bool {
820 common.status == 1
821 }
822
823 unsafe fn klu_rcond(
824 symbolic: *mut Self::KluSymbolic,
825 numeric: *mut Self::KluNumeric,
826 common: *mut Self::KluCommon,
827 ) -> bool {
828 klu_l_rcond(symbolic, numeric, common) != 0
829 }
830
831 unsafe fn klu_z_rcond(
832 symbolic: *mut Self::KluSymbolic,
833 numeric: *mut Self::KluNumeric,
834 common: *mut Self::KluCommon,
835 ) -> bool {
836 klu_zl_rcond(symbolic, numeric, common) != 0
837 }
838}