friendly / matlib

Matrix Functions for Teaching and Learning Linear Algebra and Multivariate Statistics
http://friendly.github.io/matlib/
65 stars 16 forks source link

Solve(): should it return the same result as solve()? #14

Closed friendly closed 8 years ago

friendly commented 8 years ago

Solve() prints the result in a nice character form, which it also returns invisibly. As well, it really requires, but doesn't test for, the b argument, so this gives a nonsense result:

> Solve(A)
x1    =  0 
  x2  =  0 
   0  =  1 

For consistency, perhaps our "shadow" functions should return the same form of result as their stats:: counterparts, like Det(), Eigen() do.

This would allow, e.g., Solve(A) %*% b and other uses.

john-d-fox commented 8 years ago

Hi,

I agree that Solve() should be made as compatible as possible with solve().

But Solve() is also more general, in that it works with rectangular and, more generally, overdetermined and underdetermined systems of equations.

If b is missing, what should be returned if A is singular or rectangular? Maybe a generalized inverse would be a good choice.

John

-----Original Message----- From: Michael Friendly [mailto:notifications@github.com] Sent: October 12, 2016 9:53 AM To: friendly/matlib matlib@noreply.github.com Subject: [friendly/matlib] Solve(): should it return the same result as solve()? (#14)

Solve() prints the result in a nice character form, which it also returns invisibly. As well, it really requires, but doesn't test for, the b argument, so this gives a nonsense result:

Solve(A) x1 = 0 x2 = 0 0 = 1

For consistency, perhaps our "shadow" functions should return the same form of result as their stats:: counterparts, like Det(), Eigen() do.

This would allow, e.g., Solve(A) %*% b and other uses.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/friendly/matlib/issues/14 , or mute the thread https://github.com/notifications/unsubscribe- auth/ANcgQi9XtZK_fTzEUwOXPuGzn-pg2yJnks5qzOZZgaJpZM4KUx7O . https://github.com/notifications/beacon/ANcgQktZhpnBI_0qE- 4MKMCCiwYaMqdiks5qzOZZgaJpZM4KUx7O.gif

philchalmers commented 8 years ago

I'll play the devils advocate here. I don't think Solve() should mimic, that's basically what inv() is for. Instead, why not have the b input default to a vector of zeros with the form

Solve <- function(A, b = rep(0, nrow(A)), vars, verbose=FALSE, simplify=TRUE, fractions=FALSE, ...)

This could help demonstrate the concept of the null space, and also show whether a unique solution could exist regardless of the values in b (i.e., A is invertable).

john-d-fox commented 8 years ago

I don't have a strong opinion but think that there's something to be gained by uniformity, with the matlib UC-named functions mirroring their base-R lc-named counterparts.

That said, I think that base-R solve() is poorly named, in that it's also used for matrix inverse, so I like that we introduce inv(), even if we (now) make it a synonym for Solve() with no b argument.

If, however, we reserve Solve() for systems of simultaneous equations, then letting b default to a 0-vector (i.e., a homogeneous system) makes sense to me, and would be better than the current erroneous result or throwing an error.

-----Original Message----- From: Phil Chalmers [mailto:notifications@github.com] Sent: October 12, 2016 4:54 PM To: friendly/matlib matlib@noreply.github.com Cc: Fox, John jfox@mcmaster.ca; Comment comment@noreply.github.com Subject: Re: [friendly/matlib] Solve(): should it return the same result as solve()? (#14)

I'll play the devils advocate here. I don't think Solve() should mimic, that's basically what inv() is for. Instead, why not have the b input default to a vector of zeros with the form

Solve <- function(A, b = rep(0, nrow(A)), vars, verbose=FALSE, simplify=TRUE, fractions=FALSE, ...)

This could help demonstrate the concept of the null space, and also show whether a unique solution could exist regardless of the values in b (i.e., A is invertable).

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/friendly/matlib/issues/14#issuecomment-253336100 , or mute the thread https://github.com/notifications/unsubscribe- auth/ANcgQg6YhOdCnE3mXnIh_GMqhn9H1mHnks5qzUjygaJpZM4KUx7O . https://github.com/notifications/beacon/ANcgQonhysFrLo- WEJDSoUG9sdlYCQucks5qzUjygaJpZM4KUx7O.gif

philchalmers commented 8 years ago

I guess the ultimate decision is whether Solve should be consistent with matlib's functions or with base R. I'm leaning more towards the former, because I don't like the idea that Solve will provide the same naming confusion that base R did with solve, which would also potentially deter users from the more intuitive inv() function provided. Also, I think the UC-LC name convention has already been broken in the package (cf. proj and Proj), so another here probably wouldn't hurt.

Maybe we can do the best of both worlds though by just adding a flag mimic = FALSE to the function, where if TRUE then Solve will mimic the behaviour of solve by calling inv(), else it will treat the missing b as a vector of zeros. The documentation could also point to inv(), just to make things more clear.

john-d-fox commented 8 years ago

Hi Phil,

You seem to feel much more strongly about this than I do, so I'm OK with not using Solve() for matrix inverses, in which case (as I mentioned) it makes sense to me to let b default to a 0 vector. I don't like the idea of providing both behaviours controlled by a flag -- that seems unnecessarily complicated and potentially confusing.

-----Original Message----- From: Phil Chalmers [mailto:notifications@github.com] Sent: October 12, 2016 8:30 PM To: friendly/matlib matlib@noreply.github.com Cc: Fox, John jfox@mcmaster.ca; Comment comment@noreply.github.com Subject: Re: [friendly/matlib] Solve(): should it return the same result as solve()? (#14)

I guess the ultimate decision is whether Solve should be consistent with matlib's functions or with base R. I'm leaning more towards the former, because I don't like the idea that Solve will provide the same naming confusion that base R did with solve, which would also potentially deter users from the more intuitive inv() function provided. Also, I think the UC-LC name convention has already been broken in the package (cf. proj and Proj), so another here probably wouldn't hurt.

Maybe we can do the best of both worlds though by just adding a flag mimic = FALSE to the function, where if TRUE then Solve will mimic the behaviour of solve by calling inv(), else it will treat the missing b as a vector of zeros. The documentation could also point to inv(), just to make things more clear.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/friendly/matlib/issues/14#issuecomment-253378057 , or mute the thread https://github.com/notifications/unsubscribe- auth/ANcgQggo4tM-WLWURO6nzaeRMqmm2Gueks5qzXuVgaJpZM4KUx7O . https://github.com/notifications/beacon/ANcgQuPSxMF131ZZPGMg6F0NZlqs j3auks5qzXuVgaJpZM4KUx7O.gif

friendly commented 8 years ago

OK, I'll add a zero vector as the default for b and let's leave like that.

friendly commented 8 years ago

Done