-
Notifications
You must be signed in to change notification settings - Fork 13
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
add pinv to lubeck2 and make svd nothrow #55
base: master
Are you sure you want to change the base?
Conversation
@9il please review this. |
source/kaleidic/lubeck2.d
Outdated
enforce!("svd: " ~ msg)(!info); | ||
|
||
try enforce!("svd: " ~ msg)(!info); | ||
catch(Exception e) assert(false, e.msg); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please add a test
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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:
|
source/kaleidic/lubeck2.d
Outdated
)( | ||
auto ref const Slice!(const(T)*, 2, kind) a, | ||
out size_t infoResult, | ||
out bool lowApiExecuted, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why this flag is needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
either way we check info. Do you think the flag is redundant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Already removed
source/kaleidic/lubeck2.d
Outdated
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
source/kaleidic/lubeck2.d
Outdated
return svdresult; //transposed | ||
} | ||
|
||
@safe pure @nogc nothrow SvdResult!T svdImpl |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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);