Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Panic during Matrix.solve() #2

Open
twitchyliquid64 opened this issue Sep 7, 2023 · 5 comments
Open

Panic during Matrix.solve() #2

twitchyliquid64 opened this issue Sep 7, 2023 · 5 comments

Comments

@twitchyliquid64
Copy link

        let mut m = sparse21::Matrix::from_entries(vec![
            (0, 0, 1.0),
            (0, 1, -1.0),
            (1, 0, -1.0),
            (1, 1, 1.0),
            (2, 0, 1.0),
            // (2, 2, 1.0),
        ]);

        let soln = m.solve(vec![-3.3, 3.3, 0.]).unwrap();

The matrix is:

	01	-1	  	 = -3.3
	-1	01	  	 = 3.3
	01	  	  	 = 0.0

Am I holding it wrong? must the number of rows in the matrix equal the number of variables?

@dan-fritchman
Copy link
Owner

  • That matrix/ system is singular, isn't it?
    • The zero-valued third column would seem to make it so
    • Does any other linear algebra library successfully solve that system?
  • Is the panic actually during Matrix.solve(), or from your call to unwrap() its result?
    • What is, like, the panic error message?

A few things that could help ya here:

  • Some richer error types; sparse21 really uses all &'static str
  • Methods to dump to a dense matrix, at least for debug. E.g. Matrix.to_dense<N: usize>() -> [[f64; N]; N], and then print-debug those

Noting: the most recent (although no longer all that recent) edits to sparse21 are essentially vendored into spice21:
https://github.com/dan-fritchman/Spice21/blob/main/spice21/src/sparse21/mod.rs

@twitchyliquid64
Copy link
Author

twitchyliquid64 commented Sep 8, 2023

That matrix/ system is singular, isn't it?

I had to look up what that was - yeah its a pretty weird matrix as far as whats normally fed into a solver in a circuit simulator. I was under the impression I could feed any linear equation in - perhaps thats very much not the case?

I'm sorry for my noob'ness, I'm still very much learning.

Is the panic actually during Matrix.solve(), or from your call to unwrap() its result?

  • What is, like, the panic error message?

Oops, apologies for not attaching that. Its in sparse21:

failures:

---- z::tests::sparse21_panic stdout ----
thread 'z::tests::sparse21_panic' panicked at 'index out of bounds: the len is 2 but the index is 2', /home/xxx/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sparse21-0.2.1/src/lib.rs:855:25
stack backtrace:
   0: rust_begin_unwind
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/std/src/panicking.rs:593:5
   1: core::panicking::panic_fmt
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/core/src/panicking.rs:67:14
   2: core::panicking::panic_bounds_check
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/core/src/panicking.rs:162:5
   3: <usize as core::slice::index::SliceIndex<[T]>>::index
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/core/src/slice/index.rs:261:10
   4: core::slice::index::<impl core::ops::index::Index<I> for [T]>::index
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/core/src/slice/index.rs:18:9
   5: <alloc::vec::Vec<T,A> as core::ops::index::Index<I>>::index
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/alloc/src/vec/mod.rs:2675:9
   6: sparse21::Matrix::solve
             at /home/xxx/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sparse21-0.2.1/src/lib.rs:855:25
   7: auto_ee::z::tests::sparse21_panic
             at ./src/z/mod.rs:166:20
   8: auto_ee::z::tests::sparse21_panic::{{closure}}
             at ./src/z/mod.rs:153:25
   9: core::ops::function::FnOnce::call_once
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/core/src/ops/function.rs:250:5
  10: core::ops::function::FnOnce::call_once
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.


failures:
    z::tests::sparse21_panic

test result: FAILED. 18 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.10s

error: test failed, to rerun pass `--lib`

@twitchyliquid64
Copy link
Author

twitchyliquid64 commented Sep 8, 2023

I'm also able to get a different panic with a different test I was working on, which I believe is just as singular / bad as the one in this issue:

The matrix is the same except the coefficient for the [2] variable is explicitly set to zero:

00 (NetVoltage(Netref(0))):	01	-1	  	 = -3.3
01 (NetVoltage(Netref(1))):	-1	01	  	 = 3.3
02 (GroundPin(Netref(0))):	01	  	00	 = 0.0
---- net::tests::solver_smoketest stdout ----
thread 'net::tests::solver_smoketest' panicked at 'Assertion Failed', /home/xxx/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sparse21-0.2.1/src/lib.rs:1011:9
stack backtrace:
   0: std::panicking::begin_panic
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/std/src/panicking.rs:625:12
   1: sparse21::Assert<T>::raise
             at /home/xxx/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sparse21-0.2.1/src/lib.rs:1011:9
   2: sparse21::Assert<T>::ne
             at /home/xxx/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sparse21-0.2.1/src/lib.rs:1017:53
   3: sparse21::Matrix::row_col_elim
             at /home/xxx/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sparse21-0.2.1/src/lib.rs:751:9
   4: sparse21::Matrix::lu_factorize
             at /home/xxx/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sparse21-0.2.1/src/lib.rs:585:13
   5: sparse21::Matrix::solve
             at /home/xxx/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sparse21-0.2.1/src/lib.rs:808:49
   6: auto_ee::net::DCSolver::solve
             at ./src/net/mod.rs:228:36
   7: auto_ee::net::tests::solver_smoketest
             at ./src/net/mod.rs:309:22
   8: auto_ee::net::tests::solver_smoketest::{{closure}}
             at ./src/net/mod.rs:300:27
   9: core::ops::function::FnOnce::call_once
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/core/src/ops/function.rs:250:5
  10: core::ops::function::FnOnce::call_once
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

@twitchyliquid64
Copy link
Author

Methods to dump to a dense matrix, at least for debug.

Here's what I'm using as a debug printer (produced the above output). Unfortunately I have to use my own datastructures for iteration because there doesnt seem to be a getter for the number of rows / cols:

    fn print_debug(&self) {
        for row in 0..self.eqs.len() {
            print!("{:02} ({:?}):\t", row, self.eqs[row]);
            for col in 0..self.eqs.len() {
                if let Some(v) = self.mat.get(row, col) {
                    print!("{:02}", v);
                } else {
                    print!("  ");
                }
                print!("\t");
            }
            if let Some(rhs) = self.rhs.get(&row) {
                print!(" = {:2.1}", rhs);
            }
            println!();
        }
    }

Noting: the most recent (although no longer all that recent) edits to sparse21 are essentially vendored into spice21:

Should I PR them over? At least thats something I can do 😀

@dan-fritchman
Copy link
Owner

OK so the solver is indeed panicking.

And PRs totally welcome! I would prefer to do it like this:
dan-fritchman/Spice21#20

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants