I made some simple code in C to calculate the squared of the number that a user inputs, which can be seen here:
#include <stdio.h>
int squared(int *x);
int main()
{
int num = 0;
printf("Enter an integer: \n");
scanf("%d",&num);
squared(&num);
printf("Your number squared is: %d\n",num);
system("pause");
}
int squared(int *x)
{
*x *=(*x);
}
I would like to call this in R. So I put the executable in my PATH and used system("Practice.exe") in RStudio, but this skipped the user input. I do not want to simply call a function in C, as the goal of this is to run an executable with complicated C code so that it can be wrapped in a tcltk gui in R. How can I get user input from an executable in R?
Related
I'm trying to speed up numeric computation in my R code using RcppParallel and am attempting to edit an example that uses the Cpp sqrt() function to take the square root of each element of a matrix. My edited code replaces matrices with vectors and multiplies the sqrt() by a constant. (In actual use I will have 3 constants and my own operator function.)
The example comes from
https://gallery.rcpp.org/articles/parallel-matrix-transform/
The compiler identifies the error as in the 'algorithm' file on a comment line:
Line 7 no matching function for call to object of type 'SquareRootPlus::sqrtWrapper'
This is my initial attempt to use RcppParallel and I've not used
Cpp for several years.
Edit: running macOS Ventura on apple silicon,
Rcpp ver 1.0.10,
RcppParallel ver 5.1.6,
and R version 4.2.1 (2022-06-23) -- "Funny-Looking Kid"
It would be called like this (if it compiled):
where c is a numerical constant aka a double and res is a numerical vector
res <- parallelMatrixSqrt(someNumericalVector, c)
My testing code is:
#include <Rcpp.h>
#include <RcppParallel.h>
using namespace RcppParallel;
using namespace Rcpp;
struct SquareRootPlus : public Worker
{
// source vector etc
const RVector<double> input;
const double constParam;
// destination vector
RVector<double> output;
// initialize with source and destination
// get the data type correctly unless auto promoted/cast
SquareRootPlus(const Rcpp::NumericVector input, const double constParam,
Rcpp::NumericVector output)
: input(input), constParam(constParam), output(output) {}
struct sqrt_wrapper { // describe worker function
public: double operator()(double a, double cp) {
return ::sqrt(a) * cp;
}
};
// take the square root of the range of elements requested
// (and multiply it by the constant)
void operator()(std::size_t begin, std::size_t end) {
std::transform(input.begin() + begin,
input.begin() + end,
output.begin() + begin,
sqrt_wrapper());
}
};
// public called routine
// [[Rcpp::export]]
Rcpp::NumericVector paralleVectorSqrt(Rcpp::NumericVector x, double c) {
// allocate the output matrix
Rcpp::NumericVector output(x.length());
// SquareRoot functor (pass input and output matrixes)
SquareRootPlus squareRoot(x, c, output);
// call parallelFor to do the work
parallelFor(0, x.length(), squareRoot);
// return the output matrix
return output;
}
That still works fine for me (Ubuntu 22.10, g++-12) -- modulo same warnings we often get from libraries like Boost, and here now from the include TBB library (and the repo should have a newer one so you can try that).
I just did (straight from the Rcpp Gallery source directory):
> library(Rcpp)
> sourceCpp("2014-06-29-parallel-matrix-transform.cpp")
In file included from /usr/local/lib/R/site-library/RcppParallel/include/tbb/tbb.h:41,
from /usr/local/lib/R/site-library/RcppParallel/include/RcppParallel/TBB.h:10,
from /usr/local/lib/R/site-library/RcppParallel/include/RcppParallel.h:21,
from 2014-06-29-parallel-matrix-transform.cpp:59:
/usr/local/lib/R/site-library/RcppParallel/include/tbb/concurrent_hash_map.h:343:23: warning: ‘template<class _Category, class _Tp, class _Distance, class _Pointer, class _Reference> struct std::iterator’ is dep
recated [-Wdeprecated-declarations]
[... more like this omitted for brevity ...]
> # allocate a matrix
> m <- matrix(as.numeric(c(1:1000000)), nrow = 1000, ncol = 1000)
> # ensure that serial and parallel versions give the same result
> stopifnot(identical(matrixSqrt(m), parallelMatrixSqrt(m)))
> # compare performance of serial and parallel
> library(rbenchmark)
> res <- benchmark(matrixSqrt(m),
+ parallelMatrixSqrt(m),
+ order="relative")
> res[,1:4]
test replications elapsed relative
2 parallelMatrixSqrt(m) 100 0.496 1.000
1 matrixSqrt(m) 100 0.565 1.139
>
and as you can see it not only builds but also runs the example call from R.
You would have to give us more detail about how you call it and what OS and package versions you use. And I won't have time now to dig into your code and do a code review for you but given that (still relatively simple) reference example works maybe you can reduce your currently-not-working approach down to something simpler that works.
Edit Your example appears to have switched from a unary function to one with two arguments in the signature. Sadly it ain't that easy. The fuller error message is (on my side with g++-12)
/usr/include/c++/12/bits/stl_algo.h:4263:31: error: no match for call to ‘(SquareRootPlus::sqrt_wrapper) (const double&)’
4263 | *__result = __unary_op(*__first);
| ~~~~~~~~~~^~~~~~~~~~
question.cpp:25:20: note: candidate: ‘double SquareRootPlus::sqrt_wrapper::operator()(double, double)’
25 | public: double operator()(double a, double cp) {
| ^~~~~~~~
question.cpp:25:20: note: candidate expects 2 arguments, 1 provided
So you need to rework / extend the example framework for this.
Edit 2: The gory details about std::transform() and its unary function are e.g. here at cppreference.com.
Edit 3: Building on the previous comment, when you step back a bit and look at what is happening here you may seen that RcppParellel excels at parceling up a large data structure, then submitting all the piece in parallel and finally reassemble the result. That still works. You simply cannot apply for 'richer signature function' via std::transform(). No more, no less. You need to work the guts of work which applies your function to the chunk it sees. Check the other RcppParallel examples for inspiration.
I have added this function in proc.c file
int getNumProc(void)
{
struct proc *p;
int count = 0;
acquire(&ptable.lock);
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++)
{
if(p->state != UNUSED)
count++;
}
release(&ptable.lock);
return count;
}
I have made all the necessary modifications in the following files:
defs.h
sysproc.c
syscall.h
usys.S
syscall.c
user.h
I also created a user program called totproc.c to call this system call and added this user program in Makefile at relevant places. When I type totproc command in XV6 shell the command does print that there a 3 processes. But alongside the result, it also prints the following error :
pid 4 totproc: trap 14 err 5 on cpu 1 eip 0xffffffff addr 0xffffffff--kill proc
What could be wrong here? If you were to write a system call to find the number of processes, how would you write it?
You seems to be in the right way but looks like you are missing something.
The error you are getting is being produced when an unexpected interrupt is received (in trap.c). Specifically, trap number 14 is T_PGFLT (according to trap.h).
This means the MMU answered with a page fault interrupt when some address was being tried to access, in other words, you are probably having a memory overwrite or access violation somewhere.
Consider sharing you user space application code.
Well , I figured out the problem. Turned out , the problem was not in my system call but in the user program totproc.c that made the system call. My initial totproc.c looked like this :
#include "types.h"
#include "stat.h"
#include "user.h"
int main()
{
printf(1 , "No. of Process: %d" , getNumProc());
return 0;
}
The properly working totproc.c is like below :
#include "types.h"
#include "stat.h"
#include "user.h"
#include "fcntl.h"
int main()
{
printf(1 , "No. of Process: %d" , getNumProc());
exit();
}
I'm using FFTW to compute a 2D complex to complex FFT using this code:
#include <stdlib.h>
#include "defines.h"
#include <math.h>
#include <fftw3.h>
int main(void)
{
fftw_complex *in,*out;
fftw_plan plan;
int rows=64;
int cols=64;
int i;
in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*rows*cols);
out = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*rows*cols);
for (i=0; i<rows*cols; i++)
{
in[i][0] = input_data[2*i];
in[i][1] = input_data[2*i+1];;
}
printf("### Setting plan ###\n");
plan = fftw_plan_dft_2d(rows, cols, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
printf("### Executing plan ###\n");
fftw_execute(plan);
for ( i = 0; i <rows*cols; i++ )
{
printf ( "RE = %f \t IM = %f\n",in[i][0], in[i][1] );
}
fftw_destroy_plan(plan);
fftw_free(in);
fftw_free(out);
return 0;
}
Now, I changed the FFTW flag from ESTIMATE to EXHAUSTIVE in order to allow the planner to choose the optimal algorithm for this 2D FFT but I got an all-zeros result. Can someone tell me what is wrong?
Using the flag FFTW_ESTIMATE, the function fftw_plan_dft_2d() tries to guess which FFT algorithm is the fastest without running any of them. Using the flag FFTW_EXHAUSTIVE, that function runs every possible algorithm and select the fastest one.
The problem is that the input is overwritten in the process.
The solution is to populate the input array after the plan creation!
See documentation of planner flags:
Important: the planner overwrites the input array during planning unless a saved plan (see Wisdom) is available for that problem, so you should initialize your input data after creating the plan. The only exceptions to this are the FFTW_ESTIMATE and FFTW_WISDOM_ONLY flags, as mentioned below.
I need to generate samples in C++ that follow the hypergeometric distribution. But, for my case I can approximate it with the binomial distribution without any problem.
Thus I'd like to use the std implementation in C++11. If I generate many samples at calculate the probability I get different values from the one R tells me. What is more, the difference does not get any smaller when increase the number of samples increases. The parameters are the same for R and C++.
Thus the question: Why do I not get the same results and what can I do/which should I trust?
See below, the R and C++ code. The C++ program calculates the difference to the R values. Even if I let the program run for quite a while this numbers don't get smaller but just wiggle around the E-5, E-6, E-7 magnitude.
R:
dbinom(0:2, 2, 0.48645948945615974379)
#0.26372385596962805154 0.49963330914842424280 0.23664283488194759464
C++:
#include <iostream>
#include <iomanip>
#include <random>
using namespace std;
class Generator {
public:
Generator();
virtual ~Generator();
int binom();
private:
std::random_device randev;
std::mt19937_64 gen;
std::binomial_distribution<int> dist;
};
Generator::Generator() : randev(), gen(randev()), dist(2,0.48645948945615974379) { }
Generator::~Generator() {}
int Generator::binom() { return dist(gen); }
int main() {
Generator rd;
const double nrolls = 10000000; // number of experiments
double p[3]={};
for (int k=1; k<100; ++k) {
for (int i=0; i<nrolls; ++i) {
int number = rd.binom();
++p[number];
}
cout << "Samples=" << setw(8) << nrolls*k <<
" dP(0)="<<setw(13)<<p[0]/(nrolls*k)-0.26372385596962805154<<
" dP(1)="<<setw(13)<<p[1]/(nrolls*k)-0.49963330914842424280<<
" dP(2)="<<setw(13)<<p[2]/(nrolls*k)-0.23664283488194759464<<endl;
}
cout<<"end";
return 0;
}
A selective output:
Samples= 1e+07 dP(0)= -2.0056e-05 dP(1)= 9.49909e-05 dP(2)= -7.49349e-05
Samples= 1e+08 dP(0)= 1.5064e-05 dP(1)= 3.43609e-05 dP(2)= -4.94249e-05
Samples= 9.9e+08 dP(0)= -2.06449e-05 dP(1)= 5.93429e-06 dP(2)= 1.47106e-05
This should really be a comment.
I don't see anything wrong with your numbers. You are doing 10**9 repetitions. Hence by the central limit theorem you should see accuracy around 10**(-4.5). That is indeed what you are seeing. That the signs of dP(0) and dP(2) fluctuate is another good sign. If you run your program multiple times, do the signs on the last line always show the same pattern. If not, that is another good sign.
Btw R is giving you way too many digits in my opinion. With doubles you only have about 15 digits of accuracy.
i'm trying to write a program that gets from the user a value x and prints sinx using taylor series. but my output is bad. the output i get is not even a number, its -1.#IND00 regardless of what i input.
here's my code
#include <stdio.h>
#include <conio.h>
void main()
{
int i;
double x,sum,last;
sum=(double)0;
scanf("%f",&x);
last=x;
sum=last;
for(i=1;i<10;i++)
{
last*=(double)(-x*x)/((2*i)*(2*i+1));
sum+=last;
}
printf("%f",sum);
getch();
}
I can see one problem:
scanf("%f",&x);
x is a double, so you need the l, i.e. "%lf".
[true but irrelevant point about how this isn't the right formula for sinh, even though sinh is nowhere mentioned in the question, redacted..]