There is no difference in what your form does and what mine does in terms of efficiency, on any platform. They are identical. The first time a maref is called on a non-native implementation, the marray is checked for cl-invalid. If it is T, the entire array is copied from the C side to the CL side. The exact same thing happens when cl-array is called.
On Wed, Apr 15, 2009 at 7:40 PM, Malcolm Reynolds malcolm.reynolds@gmail.com wrote:
Yeah, I guess that is fine too but I was attempting to avoid using (cl-array ..). I know you said on SBCL there is low overhead for the conversion but I figured in case that didn't hold on other CL implementations this probably does. Since it's now a generic function it seemed worth making it specific on your custom datatypes, but I appreciate what seems like it should be more optimal might not always turn out to be so..
Malcolm
On Thu, Apr 16, 2009 at 12:28 AM, Liam Healy lhealy@common-lisp.net wrote:
I'd make it simpler:
(defmethod lisp-unit:numerical-equal ((result1 marray) (result2 marray) &key (test #'lisp-unit:number-equal)) "Return true if the arrays are numerically equal according to :TEST." (when (equal (dimensions result1) (dimensions result2)) (lisp-unit:numerical-equal (cl-array result1) (cl-array result2)) :test test))
works?
Liam
On Wed, Apr 15, 2009 at 7:06 PM, Malcolm Reynolds malcolm.reynolds@gmail.com wrote:
This is what I put together quickly, seemed to work for the few cases I tried it on. It will return nil when you give it a matrix and a vector that are equal in all their values, ie the vector '(1 2 3) and the matrix '((1 2 3)) won't be equal.. I'm not sure whether that's a good or bad behaviour at this point...
(defmethod lisp-unit:numerical-equal ((result1 marray) (result2 marray) &key (test #'lisp-unit:number-equal)) "Return true if the arrays are numerically equal according to :TEST." (when (equal (dimensions result1) (dimensions result2)) (let ((m (dim0 result1)) (n (dim1 result1))) (do ((i 0 (1+ i))) ((= i m)) (do ((j 0 (1+ j))) ((= j n)) (when (not (funcall test (maref result1 i j) (maref result2 i j))) (return-from lisp-unit:numerical-equal nil)))) t)))
It could definitely be a lot more pretty, with something like the do-matrix macro I pasted in #lisp, but from the comments from tcr it seems like that macro has some subtle flaws which mean it definitely isn't ready to go in any libraries for general consumption yet.
On Wed, Apr 15, 2009 at 11:36 PM, Liam Healy lhealy@common-lisp.net wrote:
I certainly have no objections to any contributions. Go ahead and write a method and post it here. I would make a simple (numerical-equal (cl-array a) (cl-array b) ...) kind of test.
Liam
On Wed, Apr 15, 2009 at 10:46 AM, Malcolm Reynolds malcolm.reynolds@gmail.com wrote:
Thanks for adding this so quick Thomas! Just pulled down the new version and it looks good. The specialisation for gsll-marrays looks like it should be quite easy, I might even tackle it myself if Liam has no objections..
One thing that would also be useful to me in my current work is to compare matrices for some degree of approximate equality - eg if Y is the pseudoinverse of the matrix X, then the properties XYX = X and YXY = Y should hold, but there is likely to be some numerical aberrations. I thought about a function for numerical-approximately-equal, with a tolerance parameter, but now I think probably the best way to handle this is to pass in a custom :test function. Would you agree?
Malcolm
On Wed, Apr 15, 2009 at 5:02 AM, Thomas M. Hermann tmh.public@gmail.com wrote:
The NUMERICAL-EQUAL function has been implemented as a generic function in LISP-UNIT. It is specialized for the system classes NUMBER, LIST, VECTOR and ARRAY. It has been lightly tested. The documentation has not been updated. Please note that when you specialize it for your data type, a congruent argument list is (RESULT1 RESULT2 &KEY TEST). This will be clear when the documentation is updated.
Also note that the versions specialized for the CL system classes are for RESULT1 and RESULT2 of the same class, so, for example
(NUMERICAL-EQUAL LIST ARRAY) ; Not defined => an error
will throw an error. I'll get around to defining the mixed class versions later. Sooner if there is a real need for them.
Please feel free to email me bugs and further suggestions.
Cheers,
Tom
Liam Healy wrote: > I haven't defined such a predicate, but I think it's a good idea. As > you have seen, in order to do tests on marrays, I turn all the marrays > into CL arrays and do the comparisons on the result. I don't know if > it's the best possible way to do it, but it works. You get an error > from assert-numerical-equal because it uses #'numerical-equal as a > test, and that does not handle marrays. Your suggestion spurred me > to take a look at the lisp-unit source; what I'm thinking about is > changing #'numerical-equal to a generic function with some methods > pre-defined for CL classes; this would permit applications like GSLL > to add methods for their own objects. > > I've cc'ed Tom Hermann on this email; he is behind the modified > version of lisp-unit more so than I am. > Tom: what do you think of this idea? > > Liam