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
call_R is deprecated (has been but now CRAN is enforcing it). Investigate switching to pracma::romberg or re-writing the C-code. (spoiler alert: we re-write the C-code) #21
Comments
l'd like to do speed trials. So maybe we can make a new function using pracma::romberg and verify it is not too too much slower and still gives same results. Then we can work on gutting out the .c files etc so that there are no vestigial appendages. |
I've tried some things on a branch. They involve vectorizing/not vectorizing, cubature::hcubature and/or pracma::romberg and/or stats::integrate(). Nothing is working. I then found a wonderful repo that shows how to do .C() and call_R() and .Call() and eval. I am going to write things out carefully by hand and then see if I can rewrite the guts myself. |
It looks like I'm working up two solutions. I have a branch The writing is on the wall. I gotta rewrite some stuff in God help us. The options for this are the following:
Some things I found that might help think through SEXP-ing it up:
And my 3 files that I want to rewrite:
|
Made branch The goal is to simply rewrite the .C into a .Call:
All I did was
to
And then we do CMD+SHFT+B. Does it work? Q: Ok, .o files gone, does CMB+SHFT+B work? Q: Ok, we have deleted .o and made sure we have uniquely named funcitons in .c files. Does CMD+SHFT+B work? Q: Run the first example in ?gnlrim. What happens?
---> Maybe something to do with Q: Great! Before anything else, How about CMD+SHFT+E?
|
Found this from Hadley: Vectors.md and more generally R internals. From the R Internals page:
|
Okay I deleted branch replace_dotc_with_dotcall. And I'm going to remake it. I'm going to rebuild this stuff line by line. My hopes is that once I figure out the allocation stuff, the guts of the code just runs. |
Rebirth: Made branch replace_dotc_with_dotcall. Let's just make it all SEXP and only have romberg_sexp(). 1st hard lesson: If you include the This returns the length which is the number of ids nnest.
|
And this pair works as expected: the romberg_sexp:
and the int1 from within glnrim -- the print statements show I can evaluate the function as expected.
|
Ok, I'm to the point of writing line by line and found a whole section on R_alloc! Apparently, it is recommended when we need storage for C objects. From: Memory Allocation - all about R_alloc We see
so if my first R_alloc() in romberg_sexp is
Then this is saying tab1 allocates ...hours later...
Maybe I need a different way to do vectors? |
SECTION 5.13 EXTERNAL POINTERS AND WEAK REFERENCES SO THINGS were going well until I tried to do math on *max and *len. What to do? I think I can just pass max and len and they don't need to be pointers in this .Call way of doing things? Seems risky. I know pointers are important in C. And that's about all I know. Ok. so I change the SEXP max to int *max and int *len and did a cmd+shft+b and got the ol' Tb allocation error:
So, try removing pointers? Calculate these things within? |
Okay I'm going to bed. These things seem to be working well and the next line I write within romberg_sexp will be evalRfn
|
Ergh. I've been struggling on this for a while. From I can tell, the call_R() in romberg.c was nice because the void zz was made into the argument for the R-land R code (which I put right inside gnlrim and am printing values in teh same dev workflow I had going when I was working directly on romberg_sexp.c):
And saved in src/zero.c:
We can see there is a process to make the passed function into being a C-land object that can take values generated in C. I have made an analogous zero_ff, and my goal is to modify it to where it will return values on my ff as per gnlrim. See next comment. |
BREAKTHROUGH CITY.I realized that doing the finding-zeroes with the feval and whatever was rough-going because I want it to evaluate as it would in R. It's a little brainy that it returns a vector and each element is the id (nnest). If I just pass in one value at a time in a for loop in C it is just going to evaluate the first slot of Narrator: the tests worked. To see how I can make an R vector from within C without crashing everything I started at the top and read down through 5.09. And that was a treat: Section 5.09.1 show this example:
So I did this in my burgeoning R-code:
And this in the romberg_sexp.c -- pay attention to the very bottom where I set the last element of the vector to a different value to make sure I had control of the evaluation:
|
So now the bold frontier. I gotta put this stuff (CJ Geyer's statements) where the call_R is. |
I'm taking out all the zero stuff to see if my compiling issues resolve. I'm dumping them below and then I'll start on the fleshing out the code by putting CJ Geyer statements where call_R() is. First the dump: R code (commented out):
Now the src/zero.c:
Now the src/zero_ff.c:
|
Welp, taking the zero and zero_ff didn't fix the bonking. Might have to look more closely at the registering of functions. Let's do that .... here are the current contents of src/RegisterDynamicSymbol.c:
Oh yeah. Look at section 5.4: why do I have Which lists this:
Yikes! I need to change Like this? Try it and see if things improve.
Results: Still bonks. And it didn't know cMethods or call Methods. This inspired me to look at the _init files for rmutil and repeated and they look more like what the section 5.04 are talking about . So new plan! I will copy over repeated/src/repeated_init.c and make is gnlrim/src/gnlrim_init.c and register things as .C instead of .CAll. Next block --> |
Prima facie gnlrim/src/gnlrim_init.c:
First things first: change all the repeated to gnlrim and delete any functions that aren't in gnlrim. The result -- much more condensed! -- I also changed argument in regesterRoutines to NULL since we eliminated all Fortran. So here's the result and this would work (?) if I still used .C:
But we need .Call. So leaning on section 5.04, let's convert this stuff. Here it is:
And I have removed |
Oh wow.I have it running! Giving same answers as gnlmix!BUT![I'm getting some stack warning/errors]. As mentioned here in an issue for another R-package, it involves
Okay. Took some care but I think I got it done. At first I was mad -- despite running error free (a dream come true that I couldn't even fathom a few days ago) -- I was timing gnlrim as 4x slower than gnlmix. Then I realized that gnlrim(with .C()) vs gnlrim(with .Call) were about the same. For some reason gnlrim is a bit slower than gnlmix. Do you think has to do with the log(dispersion)? THat was the key difference. That and truck load of hard random intercept distributions... |
cry emoji It runs on the first example of gnlrim; but when I tried some cloglog bridge stuff it segfaults a bunch. or gives weird, warnings/errors from C-land |
I have installed R. Installed Rstudio. Still having problems. Starting to debug. Finding more good material on .Call: |
TECMO DANCE!This one weird trick makes R-developers hate them.I solved it. Things are running smoothly, not anymore crashy or slower than the .C implementation. The thing was I had an unprotected objected. The reason it was unprotected was because in the finding-zeros makeans function the comment said "no reason to protect" and maybe that is right for that particular invocation but for my usage I have to protect it and consequently unprotect it. Now things seems a lot smoother. I had this breakthough at midnight last night, and just to be safe committed it to the branch I was working on locally and just because it seemed like a good time for a Murphy's Law computer crash, I pushed the branch to github. I think the standing issues are now to take out the "state=xx" argument (which means editing gnlrim_init registration number of arguments etc) but that should be straight forward. Then I guess I need to summarize what I learned and see if I can just plug and play in |
I did another push to the branch after updating roxygen and the 10 -> 9 arguments. |
Stray observations: I've learned a lot and I'm glad I had gnlrim to hack on. Now I need to transfer and execute what I've learned to repeated
rmutil
|
Check out these nice slides for a potential algo improvement: Nice deep-dive explanation of Romberg and how (very) accurate it can be compared to other algos: |
Just tie this up: I'm leaving branch |
I've been learning about call_R.
Cool. Cool, cool, cool. I have no idea what call_R does. It was mentioned in this old version of base::Foreign.
For repeated/rmutil/gnlrim it seems
call_R
is only called in the romberg files, specifically evalRfn. I think Jim wrote evalRfn because I can only find references to it via google searches to my github repos and the following from R-help:So how about this? Experiment making gnlrim free of romberg in anticipation for doing the same rmutil and repeated. We can see how easy it would be to use pracma::romberg.
The text was updated successfully, but these errors were encountered: