add pinv to lubeck2 and make svd nothrow#55
add pinv to lubeck2 and make svd nothrow#55aferust wants to merge 7 commits intokaleidicassociates:masterfrom
Conversation
|
@9il please review this. |
| enforce!("svd: " ~ msg)(!info); | ||
|
|
||
| try enforce!("svd: " ~ msg)(!info); | ||
| catch(Exception e) assert(false, e.msg); |
There was a problem hiding this comment.
SVD isn't supposed to be nothrow with the current API. You may want to add an additoinal low-level API that will incorporate the info into the result.
| { | ||
| auto matrixScope = matrix.lightScope.lightConst; | ||
| return pinv(matrixScope, tolerance); | ||
| } |
|
What is wrong with |
Ah, I see, mldivide will require identity matrix allocation. OK then |
|
Hello, @9il, I am adapting an image stitching method (ransac homography estimation) DCV. I want to keep nogc nothrow with DCV. So, if we cannot have a function pinv nogc nothrow, I cannot do that. I have already tested my modification and I can do some elegant panaroma stitching. But yes I will add a unittest. If we don't have a nothrow solution, I will use my fork as a dependency? |
|
You didn't understand me. I suggest you to add an additional low-level API that will be |
|
damn, autocorrection replaces nothrow with throw |
|
Ok, now I am working on the RANSAC thing. When I find some time, I will review the "info" and try to be more familiar with it and add an additoinal low-level API as you suggest. Until it, let's keep this PR open. |
|
just to see what I was trying to do: https://github.com/aferust/dcv/tree/master/examples/imagestitchinghomography |
do you mean creating a nothrow duplicate of svd and call it inside the pinv? |
| else | ||
| auto si = st[0]; | ||
| auto s = svd.sigma[0 .. $ - si]; | ||
| s.each!"a = 1 / a"; |
There was a problem hiding this comment.
I haven't tried this code or anything, but I would definitely want to make sure this line shouldn't be something like s.each!"a = 1.0 / a"
There was a problem hiding this comment.
1 / is fine. It can be 1f / but 1.0 / . The last one will trigger float to double conversion.
There was a problem hiding this comment.
I agree 1f is better. I was a little concerned because the function signature doesn't constrain T to be floating point (though I imagine some of the other functions called make that restriction, it isn't immediately obvious from looking at this one if that is the case).
Yes. Please avoid code duplication. The old API should reuse the new one nothrow API. |
|
I understood. I will make the required changes when i am available. |
|
Before starting to do anything, I have just used a test code to determine an assertion workflow, but without touching anything, actually running on run.dlang.org the second assert fails. is it normal: /+dub.sdl:
dependency "lubeck" version="~>1.5.4"
+/
import std.stdio;
import mir.ndslice, mir.rc;
void main()
{
import kaleidic.lubeck;
import std.math : isClose;
auto A = iota(15).as!double.sliced(3,5) + 1;
auto A_pinv = pinv(A);
auto A1 = mtimes(A, mtimes(A_pinv, A));
auto A2 = mtimes(A_pinv, mtimes(A, A_pinv));
auto boolMat1 = zip(A, A1).map!((a,b) => a.isClose(b));
auto boolMat2 = zip(A_pinv, A2).map!((a,b) => a.isClose(b));
// for potential asserts
boolMat1.all!(aa => aa == true).writeln; // true
boolMat2.all!(aa => aa == true).writeln; // false ? only one value is different
A_pinv.writeln;
A2.writeln;
}outputs: |
|
Try this: |
| )( | ||
| auto ref const Slice!(const(T)*, 2, kind) a, | ||
| out size_t infoResult, | ||
| out bool lowApiExecuted, |
There was a problem hiding this comment.
with the original code, enforce was only triggered in the else block of if (m == 0 || n == 0), meaning that any lapack function ran. With that flag it provides the same logic. I was not going to put that flag. Then that idea seemed meaningful.
There was a problem hiding this comment.
either way we check info. Do you think the flag is redundant?
| if(lowApiExecuted) | ||
| { | ||
| enum msg ="pinv: pinv was not successful due to a convergence issue during SVD calculation."; | ||
| assert(!info, msg); |
There was a problem hiding this comment.
Do you need convergence validation for pinv function?
If so, then please do the same: two implementations of pinv, where one of them is has the info out argument.
| return svdresult; //transposed | ||
| } | ||
|
|
||
| @safe pure @nogc nothrow SvdResult!T svdImpl |
There was a problem hiding this comment.
I think just svd name overload is OK.
|
I understood, but I am outside now. I do it when İ get home
11 May 2024 Cmt 14:00 tarihinde Ilia Ki ***@***.***> şunu
yazdı:
… ***@***.**** commented on this pull request.
------------------------------
In source/kaleidic/lubeck2.d
<#55 (comment)>
:
> @@ -1228,6 +1228,28 @@ Returns: error code from CBlas
)
if (algorithm == "gesvd" || algorithm == "gesdd")
{
+
+ size_t info;
+ auto svdresult = svdImpl!(T, algorithm, kind)(a, info, slim);
+
+ enum msg = (algorithm == "gesvd" ? "svd: DBDSDC did not converge, updating process failed" : "svd: DBDSQR did not converge");
+ enforce!("svd: " ~ msg)(!info);
+
+ return svdresult; //transposed
+}
+
***@***.*** pure @nogc nothrow SvdResult!T svdImpl
I think just svd name overload is OK.
—
Reply to this email directly, view it on GitHub
<#55 (review)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACLDF6IGJM3NPUSJXCH3XK3ZBX25XAVCNFSM6AAAAABHQJZQR2VHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZDANJRGE4DCNJWGY>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
|
@9il I have added some pinv overloads. They cover possible situations. And there are no signature collisions. |
|
Folks, it seems I no longer have write access to Lubeck. End of story. |
I am sorry to hear it. I hope things positively change over time. |
|
@9il It's boost licensed. Would you want to fork it and do new work there? |
|
I prefer not to maintain the repository. I still have the code.dlang.org name First, we need to ask @Laeeth, if and where he wishes me to transfer the ownership of the The safest thing for now is for @jmh530 or @aferust to create a fork with another package name and all credentials and links to this repository. |
|
@9il I have a fork already. It doesn't let you fork it twice. |
pinv is added to lubeck2. for potential code reviewers, please confirm this:
instead of just enforce!("svd: " ~ msg)(!info);
I had to use the below version to make the function nothrow. I am using this method in DCV a lot. It might be a problem for release builds due to assert, but at least it is nothrow, and works with debug builds.
try enforce!("svd: " ~ msg)(!info);
catch(Exception e) assert(false, e.msg);