R freezes when I call a C code - c

I wrote a small C code to do random walk metropolis, which I call in R. When I run it, R freezes. I am not sure which part of the code is incorrect. I following this Peng and Leeuw tutorial (on Page 6). As a disclaimer: I don't have much experience with C, and have only some basic knowledge of C++
#----C code --------
#include <R.h>
#include <Rmath.h>
void mcmc(int *niter, double *mean, double *sd, double *lo_bound,
double *hi_bound, double *normal)
{
int i, j;
double x, x1, h, p;
x = runif(-5, 5);
for(i=0; i < *niter; i++) {
x1 = runif(*lo_bound, *hi_bound);
while((x1 + x) > 5 || (x1 + x) < -5)
x1 = runif(*lo_bound, *hi_bound);
h = dnorm(x+x1, *mean, *sd, 0)/dnorm(x, *mean, *sd, 0);
if(h >= 1)
h = 1;
p = runif(0, 1);
if(p < h)
x += x1;
normal[i] = x;
}
}
#-----R code ---------
foo_C<-function(mean, sd, lo_bound, hi_bound, niter)
{
result <- .C("mcmc", as.integer(niter), as.double(mean), as.double(sd),
as.double(lo_bound), as.double(hi_bound), normal=double(niter))
result[["normal"]]
}
After compiling it:
dyn.load("foo_C.so")
foo_C(0, 1, -0.5, 0.5, 100)
FOLLOW UP:
The while loop is where the problem lies. But the root of the problem seems to have to do with the function runif, which is supposed to generate a random variable between a lower bound and an upper bound. But it seems that what the function actually does is to randomly pick either the upper bound value (5) or the lower bound value (-5).

You need to follow the instructions in Writing R Extensions, section 6.3 Random number generation and call GetRNGstate(); before you call R's random number generation routines. You also need to call PutRNGstate(); when you're finished.
The reason your code started working is likely because you called set.seed in the R session before you called your mcmc C function.
So your C code should look like this:
#include <R.h>
#include <Rmath.h>
void mcmc(int *niter, double *mean, double *sd, double *lo_bound,
double *hi_bound, double *normal)
{
int i;
double x, x1, h, p;
GetRNGstate();
x = runif(-5.0, 5.0);
for(i=0; i < *niter; i++) {
x1 = runif(*lo_bound, *hi_bound);
while((x1 + x) > 5.0 || (x1 + x) < -5.0) {
x1 = runif(*lo_bound, *hi_bound);
//R_CheckUserInterrupt();
}
h = dnorm(x+x1, *mean, *sd, 0)/dnorm(x, *mean, *sd, 0);
if(h >= 1)
h = 1;
p = runif(0, 1);
if(p < h)
x += x1;
normal[i] = x;
}
PutRNGstate();
}

Related

How to implement natural logarithm with continued fraction in C?

Here I have a little problem. Create something from this formula:
This is what I have, but it doesn't work. Franky, I really don't understand how it should work.. I tried to code it with some bad instructions. N is number of iteration and parts of fraction. I think it leads somehow to recursion but don't know how.
Thanks for any help.
double contFragLog(double z, int n)
{
double cf = 2 * z;
double a, b;
for(int i = n; i >= 1; i--)
{
a = sq(i - 2) * sq(z);
b = i + i - 2;
cf = a / (b - cf);
}
return (1 + cf) / (1 - cf);
}
The central loop is messed. Reworked. Recursion not needed either. Just compute the deepest term first and work your way out.
double contFragLog(double z, int n) {
double zz = z*z;
double cf = 1.0; // Important this is not 0
for (int i = n; i >= 1; i--) {
cf = (2*i -1) - i*i*zz/cf;
}
return 2*z/cf;
}
void testln(double z) {
double y = log((1+z)/(1-z));
double y2 = contFragLog(z, 8);
printf("%e %e %e\n", z, y, y2);
}
int main() {
testln(0.2);
testln(0.5);
testln(0.8);
return 0;
}
Output
2.000000e-01 4.054651e-01 4.054651e-01
5.000000e-01 1.098612e+00 1.098612e+00
8.000000e-01 2.197225e+00 2.196987e+00
[Edit]
As prompted by #MicroVirus, I found double cf = 1.88*n - 0.95; to work better than double cf = 1.0;. As more terms are used, the value used makes less difference, yet a good initial cf requires fewer terms for a good answer, especially for |z| near 0.5. More work could be done here as I studied 0 < z <= 0.5. #MicroVirus suggestion of 2*n+1 may be close to my suggestion due to an off-by-one of what n is.
This is based on reverse computing and noting the value of CF[n] as n increased. I was surprised the "seed" value did not appear to be some nice integer equation.
Here's a solution to the problem that does use recursion (if anyone is interested):
#include <math.h>
#include <stdio.h>
/* `i` is the iteration of the recursion and `n` is
just for testing when we should end. 'zz' is z^2 */
double recursion (double zz, int i, int n) {
if (!n)
return 1;
return 2 * i - 1 - i * i * zz / recursion (zz, i + 1, --n);
}
double contFragLog (double z, int n) {
return 2 * z / recursion (z * z, 1, n);
}
void testln(double z) {
double y = log((1+z)/(1-z));
double y2 = contFragLog(z, 8);
printf("%e %e %e\n", z, y, y2);
}
int main() {
testln(0.2);
testln(0.5);
testln(0.8);
return 0;
}
The output is identical to the solution above:
2.000000e-01 4.054651e-01 4.054651e-01
5.000000e-01 1.098612e+00 1.098612e+00
8.000000e-01 2.197225e+00 2.196987e+00

Golden Section Method in C

I am pretty new to coding and I have been having an impossible time trying to find online help writing a C code that will use the golden section method (which apparently the GNU Scientific Library has, although I haven't had any luck finding it) to find the minimum of functions that Newton's method of minimization fails for.
Specifically I want to input an x-value as a starting point and have the code output the function's minimum value and the x coordinate of the minimum value point. My function is f(x) = x20. I am also allowed some error (< 10-3).
I don't even know where to begin with this, I have been ALL over the internet and haven't found anything helpful. I would seriously appreciate some help as to where I might find more information, or how I might implement this method.
Edit:
This is my code as of now:
#include <gsl/gsl_errno.h> /* Defines GSL_SUCCESS, etc. */
#include <gsl/gsl_math.h>
#include <gsl/gsl_min.h>
int minimize_convex(gsl_function *F,double a, double b, double *x_min, double tol)
{
int status;
double h = (b - a) * .0000001; /* Used to test slope at boundaries */
/* First deal with the special cases */
if (b - a < tol)
{
*x_min = b;
status = GSL_SUCCESS;
}
/* If the min is at a, then the derivative at a is >= 0. Test for
* this case. */
else if (GSL_FN_EVAL(F, a + h) - GSL_FN_EVAL(F, a) >= 0)
{
*x_min = a;
status = GSL_SUCCESS;
}
/* If the min is at b, then the derivative at b is >= 0. Test for
* this case. */
else if (GSL_FN_EVAL(F, b - h) - GSL_FN_EVAL(F, b) >= 0)
{
*x_min = b;
status = GSL_SUCCESS;
}
else
{
/* Choose x_guess so that it's value is less than either of the two
* endpoint values. Since we've got this far, we know that at least
* of of F(a + h) and F(b - h) has this property. */
double x_guess;
x_guess = (GSL_FN_EVAL(F, a + h) < GSL_FN_EVAL(F, b - h)) ?
a + h : b - h;
int iter = 0, max_iter = 200;
const gsl_min_fminimizer_type *T;
gsl_min_fminimizer *s;
T = gsl_min_fminimizer_goldensection;
s = gsl_min_fminimizer_alloc(T);
gsl_min_fminimizer_set(s, F, x_guess, a, b);
do
{
iter++;
status = gsl_min_fminimizer_iterate(s); /* perform iteration */
status =
gsl_min_test_interval(a, b, tol, 0.0); /* |a - b| < tol? */
a = gsl_min_fminimizer_x_lower(s);
b = gsl_min_fminimizer_x_upper(s);
if (status == GSL_SUCCESS)
{
*x_min = gsl_min_fminimizer_x_minimum(s); /* current est */
}
}
while (status == GSL_CONTINUE && iter < max_iter);
gsl_min_fminimizer_free(s);
}
return status;
}
double f(double x, void *params)
{
double *p = (double *) params;
return (x^(50)) + *p;
}
double C = 0.0;
int main (void)
{
double m = 0.0, result;
double a = -1.0, b = 1.0;
double epsilon = 0.001;
int exit_val;
gsl_function F;
F.function = &f;
F.params = &C;
exit_val = minimize_convex(&F, a, b, m, &result, epsilon);
printf("Minimizer: %g\n", result);
printf("Function value: %g\n", f(result, &C));
printf("%d\n", exit_val);
return 0;
}
I am getting the following errors:
try.c:69:14: error: invalid operands to binary
expression ('double' and 'double')
return (x^(50)) + *p;
try.c:81:54: error: too many arguments to function
call, expected 5, have 6
exit_val = minimize_convex(&F, a, b, m, &result, epsilon);
Any thoughts?
gsl has a generic minimizer that can use multiple methods to acheive the minimization. The description of how to use the minimizer can be found in the documentation. You can set it to the golden section method by delcaring the method as gsl_min_fminimizer_goldensection.

Own asin() function (with Taylor series) not accurate

I need to write my own asin() function without math.h library with the use of Taylor series. It works fine for numbers between <-0.98;0.98> but when I am close to limits it stops with 1604 iterations and therefore is inaccurate.
I don't know how to make it more accurete. Any suggestions are very appreciated!
The code is following:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define EPS 0.000000000001
double my_arcsin(double x)
{
long double a, an, b, bn;
a = an = 1.0;
b = bn = 2.0;
long double n = 3.0;
double xn;
double xs = x;
double xp = x;
int iterace = 0;
xn = xs + (a/b) * (my_pow(xp,n) / n);
while (my_abs(xn - xs) >= EPS)
{
n += 2.0;
an += 2.0;
bn += 2.0;
a = a * an;
b = b * bn;
xs = xn;
xn = xs + (a/b) * (my_pow(xp,n) / n);
iterace++;
}
//printf("%d\n", iterace);
return xn;
}
int main(int argc, char* argv[])
{
double x = 0.0;
if (argc > 2)
x = strtod(argv[2], NULL);
if (strcmp(argv[1], "--asin") == 0)
{
if (x < -1 || x > 1)
printf("nan\n");
else
{
printf("%.10e\n", my_arcsin(x));
//printf("%.10e\n", asin(x));
}
return 0;
}
}
And also a short list of my values and expected ones:
My values Expected values my_asin(x)
5.2359877560e-01 5.2359877560e-01 0.5
1.5567132089e+00 1.5707963268e+00 1 //problem
1.4292568534e+00 1.4292568535e+00 0.99 //problem
1.1197695150e+00 1.1197695150e+00 0.9
1.2532358975e+00 1.2532358975e+00 0.95
Even though the convergence radius of the series expansion you are using is 1, therefore the series will eventually converge for -1 < x < 1, convergence is indeed painfully slow close to the limits of this interval. The solution is to somehow avoid these parts of the interval.
I suggest that you
use your original algorithm for |x| <= 1/sqrt(2),
use the identity arcsin(x) = pi/2 - arcsin(sqrt(1-x^2)) for 1/sqrt(2) < x <= 1.0,
use the identity arcsin(x) = -pi/2 + arcsin(sqrt(1-x^2)) for -1.0 <= x < -1/sqrt(2).
This way you can transform your input x into [-1/sqrt(2),1/sqrt(2)], where convergence is relatively fast.
PLEASE NOTICE: In this case I strongly recommend #Bence's method, since you can't expect a slowly convergent method with low data accuracy to obtain arbitrary precision.
However I'm willing to show you how to improve the result using your current algorithm.
The main problem is that a and b grows too fast and soon become inf (after merely about 150 iterations). Another similar problem is my_pow(xp,n) grows fast when n grows, however this doesn't matter much in this very case since we could assume the input data goes inside the range of [-1, 1].
So I've just changed the method you deal with a/b by introducing ab_ratio, see my edited code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define EPS 0.000000000001
#include <math.h>
#define my_pow powl
#define my_abs fabsl
double my_arcsin(double x)
{
#if 0
long double a, an, b, bn;
a = an = 1.0;
b = bn = 2.0;
#endif
unsigned long _n = 0;
long double ab_ratio = 0.5;
long double n = 3.0;
long double xn;
long double xs = x;
long double xp = x;
int iterace = 0;
xn = xs + ab_ratio * (my_pow(xp,n) / n);
long double step = EPS;
#if 0
while (my_abs(step) >= EPS)
#else
while (1) /* manually stop it */
#endif
{
n += 2.0;
#if 0
an += 2.0;
bn += 2.0;
a = a * an;
b = b * bn;
#endif
_n += 1;
ab_ratio *= (1.0 + 2.0 * _n) / (2.0 + 2.0 * _n);
xs = xn;
step = ab_ratio * (my_pow(xp,n) / n);
xn = xs + step;
iterace++;
if (_n % 10000000 == 0)
printf("%lu %.10g %g %g %g %g\n", _n, (double)xn, (double)ab_ratio, (double)step, (double)xn, (double)my_pow(xp, n));
}
//printf("%d\n", iterace);
return xn;
}
int main(int argc, char* argv[])
{
double x = 0.0;
if (argc > 2)
x = strtod(argv[2], NULL);
if (strcmp(argv[1], "--asin") == 0)
{
if (x < -1 || x > 1)
printf("nan\n");
else
{
printf("%.10e\n", my_arcsin(x));
//printf("%.10e\n", asin(x));
}
return 0;
}
}
For 0.99 (and even 0.9999999) it soon gives correct results with more than 10 significant digits. However it gets slow when getting near to 1.
Actually the process has been running for nearly 12 minutes on my laptop calculating --asin 1, and the current result is 1.570786871 after 3560000000 iterations.
UPDATED: It's been 1h51min now and the result 1.570792915 and iteration count is 27340000000.

Calculating exponents in C without pow()

int main ()
{
int n = 0;
int base = 0;
while(n < 10)
{
int x = 2;
int answer = power(x, n);
float neganswer = negpower(x, n);
printf("%d %d %f\n", base, answer, neganswer);
base++;
n++;
}
return EXIT_SUCCESS;
}
int power(int base, int power)
{
int result, i;
result = 1;
for (i=0; i < power; i++)
{
result *= base;
}
return result;
}
int negpower(int base, int power)
{
float result, i;
result = 1.0;
for (i=0; i < power; i++)
{
result = result / base;
}
return result;
}
So I'm trying to call upon this function that i've made, and I think its calculating it correctly, however it is only outputting 1.0000000 followed directly by 0.0000000. I think I've got problems with carrying the float value, can anyone chime in?
Thanks
This is because you are returning a float from negpower() which has return type of int and assigning it to a float neganswer.
Change
int negpower(int base, int power)
to
float negpower(int base, int power)
Output:
Side note:
Always add required header files.
A prototype should be declared if a function definition appears after the main().
The answer is much simpler. Your negpower function returns an int, when you actually return a float from it. Change the prototype and it should work alright.
This is optimized library if you are interested:
#ifdef DOCUMENTATION
title pow x raised to power y
index x raised to power y
usage
.s
double x, y, f, pow();
.br
f = pow(x, y);
.s
description
.s
Returns value of x raised to power y
.s
diagnostics
.s
There are three error possible error messages from this function.
.s
If the x argument is negative the message 'pow arg negative',
followed by the value of x, is written to stderr. The value
of pow for |x| is returned.
.s
If x = 0.0 and y <= 0.0 or if result overflows the message 'pow
overflow', followed by the value of y, is written to stderr.
The value of HUGE is returned.
.s
If the result underflows and if warnings are enabled (normally not),
the message 'pow underflow', followed by the value of y, is written
to stderr. The value of 0 is returned.
.s
The suggestion of Cody and Waite, that the domain be reduced to
simplify the overflow test, has been adopted, consequently overflow
is reported if the result would exceed HUGE * 2**(-1/16).
2**(-1/16) is approximately 0.9576.
.s
internal
.s
Algorithm from Cody and Waite pp. 84-124. This algorithm required
two auxiliary programs POWGA1 and POWGA2 to calculate, respectively,
the arrays a1[] and a2[] used to represent the powers of 2**(-1/16)
to more than machine precision.
The source code for these programs are in the files POWGA1.AUX and
POWGA2.AUX. The octal table on page 98 of Cody and Waite is in the
file POWOCT.DAT which is required on stdin by POWGA2.
.s
author
.s
Hamish Ross.
.s
date
.s
27-Jan-85
#endif
#include <math.h>
#define MAXEXP 2031 /* (MAX_EXP * 16) - 1 */
#define MINEXP -2047 /* (MIN_EXP * 16) - 1 */
static double a1[] = {
1.0,
0.95760328069857365,
0.91700404320467123,
0.87812608018664974,
0.84089641525371454,
0.80524516597462716,
0.77110541270397041,
0.73841307296974966,
0.70710678118654752,
0.67712777346844637,
0.64841977732550483,
0.62092890603674203,
0.59460355750136054,
0.56939431737834583,
0.54525386633262883,
0.52213689121370692,
0.50000000000000000
};
static double a2[] = {
0.24114209503420288E-17,
0.92291566937243079E-18,
-0.15241915231122319E-17,
-0.35421849765286817E-17,
-0.31286215245415074E-17,
-0.44654376565694490E-17,
0.29306999570789681E-17,
0.11260851040933474E-17
};
static double p1 = 0.833333333333332114e-1;
static double p2 = 0.125000000005037992e-1;
static double p3 = 0.223214212859242590e-2;
static double p4 = 0.434457756721631196e-3;
static double q1 = 0.693147180559945296e0;
static double q2 = 0.240226506959095371e0;
static double q3 = 0.555041086640855953e-1;
static double q4 = 0.961812905951724170e-2;
static double q5 = 0.133335413135857847e-2;
static double q6 = 0.154002904409897646e-3;
static double q7 = 0.149288526805956082e-4;
static double k = 0.442695040888963407;
double pow(x, y)
double x, y;
{
double frexp(), g, ldexp(), r, u1, u2, v, w, w1, w2, y1, y2, z;
int iw1, m, p;
if (y == 0.0)
return(1.0);
if (x <= 0.0) {
if (x == 0.0) {
if (y > 0.0)
return(x);
cmemsg(FP_POWO, &y);
return(HUGE);
}
else {
cmemsg(FP_POWN, &x);
x = -x;
}
}
g = frexp(x, &m);
p = 0;
if (g <= a1[8])
p = 8;
if (g <= a1[p + 4])
p += 4;
if (g <= a1[p + 2])
p += 2;
p++;
z = ((g - a1[p]) - a2[p / 2]) / (g + a1[p]);
z += z;
v = z * z;
r = (((p4 * v + p3) * v + p2) * v + p1) * v * z;
r += k * r;
u2 = (r + z * k) + z;
u1 = 0.0625 * (double)(16 * m - p);
y1 = 0.0625 * (double)((int)(16.0 * y));
y2 = y - y1;
w = u2 * y + u1 * y2;
w1 = 0.0625 * (double)((int)(16.0 * w));
w2 = w - w1;
w = w1 + u1 * y1;
w1 = 0.0625 * (double)((int)(16.0 * w));
w2 += (w - w1);
w = 0.0625 * (double)((int)(16.0 * w2));
iw1 = 16.0 * (w1 + w);
w2 -= w;
while (w2 > 0.0) {
iw1++;
w2 -= 0.0625;
}
if (iw1 > MAXEXP) {
cmemsg(FP_POWO, &y);
return(HUGE);
}
if (iw1 < MINEXP) {
cmemsg(FP_POWU, &y);
return(0.0);
}
m = iw1 / 16;
if (iw1 >= 0)
m++;
p = 16 * m - iw1;
z = ((((((q7*w2 + q6)*w2 + q5)*w2 + q4)*w2 + q3)*w2 + q2)*w2 + q1)*w2;
z = a1[p] + a1[p] * z;
return(ldexp(z, m));
}
You have all sorts of ints in there. When you do that, the decimal gets truncated. You should make your power functions return floats, and use a float base.

How to generate a set of points that are equidistant from each other and lie on a circle

I am trying to generate an array of n points that are equidistant from each other and lie on a circle in C. Basically, I need to be able to pass a function the number of points that I would like to generate and get back an array of points.
It's been a really long time since I've done C/C++, so I've had a stab at this more to see how I got on with it, but here's some code that will calculate the points for you. (It's a VS2010 console application)
// CirclePoints.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "stdio.h"
#include "math.h"
int _tmain()
{
int points = 8;
double radius = 100;
double step = ((3.14159265 * 2) / points);
double x, y, current = 0;
for (int i = 0; i < points; i++)
{
x = sin(current) * radius;
y = cos(current) * radius;
printf("point: %d x:%lf y:%lf\n", i, x, y);
current += step;
}
return 0;
}
Try something like this:
void make_circle(float *output, size_t num, float radius)
{
size_t i;
for(i = 0; i < num; i++)
{
const float angle = 2 * M_PI * i / num;
*output++ = radius * cos(angle);
*output++ = radius * sin(angle);
}
}
This is untested, there might be an off-by-one hiding in the angle step calculation but it should be close.
This assumes I understood the question correctly, of course.
UPDATE: Redid the angle computation to not be incrementing, to reduce float precision loss due to repeated addition.
Here's a solution, somewhat optimized, untested. Error can accumulate, but using double rather than float probably more than makes up for it except with extremely large values of n.
void make_circle(double *dest, size_t n, double r)
{
double x0 = cos(2*M_PI/n), y0 = sin(2*M_PI/n), x=x0, y=y0, tmp;
for (;;) {
*dest++ = r*x;
*dest++ = r*y;
if (!--n) break;
tmp = x*x0 - y*y0;
y = x*y0 + y*x0;
x = tmp;
}
}
You have to solve this in c language:
In an x-y Cartesian coordinate system, the circle with centre coordinates (a, b) and radius r is the set of all points (x, y) such that
(x - a)^2 + (y - b)^2 = r^2
Here's a javascript implementation that also takes an optional center point.
function circlePoints (radius, numPoints, centerX, centerY) {
centerX = centerX || 0;
centerY = centerY || 0;
var
step = (Math.PI * 2) / numPoints,
current = 0,
i = 0,
results = [],
x, y;
for (; i < numPoints; i += 1) {
x = centerX + Math.sin(current) * radius;
y = centerY + Math.cos(current) * radius;
results.push([x,y]);
console.log('point %d # x:%d, y:%d', i, x, y);
current += step;
}
return results;
}

Resources