A vector of polynomials each defined as a function - polynomials

I'm trying to get a vector of polynomials, but within the vector have each polynomial defined by a function in Pari.
For example, I want to be able to output a vector of this form:
[f(x) = x-1 , f(x) = x^2 - 1, f(x) = x^3 - 1, f(x) = x^4 - 1, f(x) = x^5 - 1]
A simple vector construction of vector( 5, n, f(x) = x^n-1) doesn't work, outputting [(x)->my(i=1);x^i-1, (x)->my(i=2);x^i-1, (x)->my(i=3);x^i-1, (x)->my(i=4);x^i-1, (x)->my(i=5);x^i-1].
Is there a way of doing this quite neatly?
Update:
I have a function which takes a polynomial in two variables (say x and y), replaces one of those variables (say y) with exp(I*t), and then integrates this between t=0 and t=1, giving a single variable polynomial in x: int(T)=intnum(t=0,1,T(x,exp(I*t)))
Because of the way this is defined, I have to explicitly define a polynomial T(x,y)=..., and then calculate int(T). Simply putting in a polynomial, say int(x*y)-1, returns:
*** at top-level: int(x*y-1)
*** ^----------
*** in function int: intnum(t=0,1,T(x,exp(I*t)))
*** ^--------------
*** not a function in function call
*** Break loop: type 'break' to go back to GP prompt
I want to be able to do this for many polynomials, without having to manually type T(x,y)=... for every single one. My plan is to try and do this using the apply feature (so, putting all the polynomials in a vector - for a simple example, vector(5, n, x^n*y-1)). However, because of the way I've defined int, I would need to have each entry in the vector defined as T(x,y)=..., which is where my original question spawned from.
Defining T(x,y)=vector(5, n, x^n*y-1) doesn't seem to help with what I want to calculate. And because of how int is defined, I can't think of any other way to go about trying to tackle this.
Any ideas?

The PARI inbuilt intnum function takes as its third argument an expression rather than a function. This expression can make use of the variable t. (Several inbuilt functions behave like this - they are not real functions).
Your int function can be defined as follows:
int(p)=intnum(t=0, 1, subst(p, y, exp(I*t)))
It takes as an argument a polynomial p and then it substitutes for y when required to do so.
You can then use int(x*y) which returns (0.84147098480789650665250232163029899962 + 0.45969769413186028259906339255702339627*I)*x'.
Similarly you can use apply with a vector of polynomials. For example:
apply(int, vector(5, n, x^n*y-1))
Coming back to your original proposal - it's not technically wrong and will work. I just wouldn't recommend it over the subst method, but perhaps if you are were wanting to perform numerical integration over a class of functions that were not representable as polynomials. Let's suppose int is defined as:
int(T)=intnum(t=0,1,T(x,exp(I*t)))
You can invoke it using the syntax int((x,y) -> x*y). The arrow is the PARI syntax for creating an anonymous function. (This is the difference between an expression and a function - you cannot create your own functions that work like PARI inbuilt functions)
You may even use it with a vector of functions:
apply(int, vector(5, n, (x,y)->x^n*y-1))
I am using the syntax (x,y)->x^n*y-1 here which is preferable to the f(x,y)=x^n*y-1 you had in your question, but they are essentially the same. (the latter form also defines f as a side effect which is not wanted so it is better to use anonymous functions.

Related

Saving a complex number in a variable

I am trying to perform this computation which results in a complex number. However, C++ gives me "NaN".
double Q, r, Theta;
Q=-0.043543950754930;
r=0.009124131609174;
Theta=acos(r/sqrt(pow(-Q,3)));
// result must be (0.00000000000000 + 0.0911033580003565i)
Yes, by using the std::complex type:
#include <complex>
#include <iostream>
int main()
{
std::complex<double> Q = -0.043543950754930;
std::complex<double> r = 0.009124131609174;
std::complex<double> Theta = std::acos(r / std::sqrt(std::pow(-Q, 3)));
std::cout << Theta << '\n';
}
Note that the complex functions return values in specific ranges. You may have to adjust for this if you are looking for a specific answer.
I am trying to perform this computation which results in a complex number.
All the variables in the posted snippet are of type double, so that the compiler has to use the overloads of std::acos, std::sqrt and std::pow accepting parameters of type double and returning double values.
In particular, the function double std::acos(double arg)[1]:
If a domain error occurs, an implementation-defined value is returned (NaN where supported).
[...]
Domain error occurs if arg is outside the range [-1.0, 1.0].
Given the values of R and Q in the posted example, the value of arg is greater than 1, causing a domain error.
To obtain a complex value, the OP should use (or cast to) variables of type std::complex<double>, so that the "correct" overloads of the mathematical functions are chosen, as well as the expected return type.
They could also implement different numerical algorithms (one for real, one for complex values) and let the program choose the right path based upon the value of some "discriminant" variable. E.g. a cubic equation has three complex solutions in general, but those can either be three different real values or three real values (two coincident) or one real value and two complex conjugate ones. A program might use different methods instead of a single general (all complex) one.
[1] Quotes from https://en.cppreference.com/w/cpp/numeric/math/acos, emphasis mine.

Calling Stan routines from a C++ program

I read here that it is possible (and I interpreted straightforward) to call Stan routines from a C++ program.
I have some complex log-likelihood functions which I have coded up in C++ and really have no idea how I could code them using the Stan language. Is it possible to call the Monte Carlo routines in Stan using the log-likelihood function I have already coded in C++? If so are there any examples of this?
It seems like quite a natural thing to do but I cannot find any examples or pointers as to how to do this.
Upon further review (you may want to unaccept my previous answer), you could try this: Write a .stan program with a user-defined function in the functions block that has the correct signature (and parses) but basically does nothing. Like this
functions {
real foo_log(real[] y, vector beta, matrix X, real sigma) {
return not_a_number(); // replace this after parsing to C++
}
}
data {
int<lower=1> N;
int<lower=1> K;
matrix[N,K] X;
real y[N];
}
parameters {
vector[K] beta;
real<lower=0> sigma;
}
model {
y ~ foo(beta, X, sigma);
// priors here
}
Then, use CmdStan to compile that model, which will generate a .hpp file as an intermediate step. Edit that .hpp file inside the body of foo_log to call your templated C++ function and also #include the header file(s) where your stuff is defined. Then recompile and execute the binary.
That might actually work for you, but if whatever you are doing is somewhat widely useful, we would love for you to contribute the C++ stuff.
I think your question is a bit different from the one you linked to. He had a complete Stan program and wanted to drive it from C++, whereas you are asking if you could circumvent writing a Stan program by calling an external C++ function to evaluate the log-likelihood. But that would not get you very far because you still have to pass in the data in a form that Stan can handle, declare to Stan what are the unknown parameters (plus their support), etc. So, I don't think you can (or should) evade learning the Stan language.
But it is fairly easy to expose a C++ function to the Stan language, which essentially just involves adding your my_loglikelihood.hpp file in the right place under ${STAN_HOME}/lib/stan_math_${VERSION}/stan/math/, adding an include statement to the math.hpp file in that subdirectory, and editing ${STAN_HOME}/src/stan/lang/function_signatures.h. At that point, your .stan program could look as simple as
data {
// declare data like y, X, etc.
}
parameters {
// declare parameters like theta
}
model {
// call y ~ my_logliklihood_log(theta, X)
}
But I think the real answer to your question is that if you have already written a C++ function to evaluate the log-likelihood, then rewriting it in the Stan language shouldn't take more than a few minutes. The Stan language is very C-like so that it is easier to parse the .stan file into a C++ source file. Here is a Stan function I wrote for the log-likelihood of a conditionally Gaussian outcome in a regression context:
functions {
/**
* Increments the log-posterior with the logarithm of a multivariate normal
* likelihood with a scalar standard deviation for all errors
* Equivalent to y ~ normal(intercept + X * beta, sigma) but faster
* #param beta vector of coefficients (excluding intercept)
* #param b precomputed vector of OLS coefficients (excluding intercept)
* #param middle matrix (excluding ones) typically precomputed as crossprod(X)
* #param intercept scalar (assuming X is centered)
* #param ybar precomputed sample mean of the outcome
* #param SSR positive precomputed value of the sum of squared OLS residuals
* #param sigma positive value for the standard deviation of the errors
* #param N integer equal to the number of observations
*/
void ll_mvn_ols_lp(vector beta, vector b, matrix middle,
real intercept, real ybar,
real SSR, real sigma, int N) {
increment_log_prob( -0.5 * (quad_form_sym(middle, beta - b) +
N * square(intercept - ybar) + SSR) /
square(sigma) - # 0.91... is log(sqrt(2 * pi()))
N * (log(sigma) + 0.91893853320467267) );
}
}
which is basically just me dumping what could otherwise be C-syntax into the body of a function in the Stan language that is then callable in the model block of a .stan program.
So, in short, I think it would probably be easiest for you to rewrite your C++ function as a Stan function. However, it is possible that your log-likelihood involves something exotic for which there is currently no corresponding Stan syntax. In that case, you could fall back to exposing that C++ function to the Stan language and ideally making pull requests to the math and stan repositories on GitHub under stan-dev so that other people could use it (although then you would also have to write unit-tests, documentation, etc.).

block and expression must have a const value error

I would like to create a matrix B from a block of matrix A. The size of A changes, so I'm trying to achieve the following
Eigen::MatrixXd B(A.block<3,N>(0,0));
where N is columns number of A. I get this error the expression must have constant value. How can I solve this problem? I've tried to use const_cast<> but I still get the same problem.
I think this would work:
Eigen::MatrixXd B = A.block(0, 0, 3, N);
The API documentation of eigen is here.
If N is a variable, it can't be used as a template function argument (<3,N>) because those must be compile-time constants (the compiler generates/instanciates a version of the function block for each combination or template arguments.)

C++ recursive function, calling current depth

I'm writing a function for calculating integrals recursively, using the trapezoid rule. For some f(x) on the interval (a,b), the method is to calculate the area of the big trapezoid with side (b-a) and then compare it with the sum of small trapezoids formed after dividing the interval into n parts. If the difference is larger than some given error, the function is called again for each small trapezoid and the results summed. If the difference is smaller, it returns the arithmetic mean of the two values.
The function takes two parameters, a function pointer to the function which is to be integrated and a constant reference to an auxiliary structure, which contains information such as the interval (a,b), the amount of partitions, etc:
struct Config{
double min,max;
int partitions;
double precision;
};
The problem arises when I want to change the amount of partitions with each iteration, for the moment let's say just increment by one. I see no way of doing this without resorting to calling the current depth of the recurrence:
integrate(const Config &conf, funptr f){
double a=conf.min,b=conf.max;
int n=conf.partitions;
//calculating the trapezoid areas here
if(std::abs(bigTrapezoid-sumOfSmallTrapezoids) > conf.precision){
double s=0.;
Config configs = new Config[n];
int newpartitions = n+(calls);
for(int i=0; i < n;++i){
configs[i]={ a+i*(b-a)/n , a+(i+1)*(b-a)/n , newpartitions};
s+=integrate(configs[i],f);
}
delete [] configs;
return s; }
else{
return 0.5*(bigTrapezoid+sumOfSmallTrapezoids);}
}
The part I'm missing here is of course a way to find (calls). I have tried doing something similar to this answer, but it does not work, in fact it freezes the pc until makefile kills the process. But perhaps I'm doing it wrong. I do not want to add an extra parameter to the function or an additional variable to the structure. How should I proceed?
You cannot "find" calls, but you can definitely pass it yourself, like this:
integrate(const Config &conf, funptr f, int calls=0) {
...
s+=integrate(configs[i],f, calls+1);
...
}
It seems to me that 'int newpartitions = n + 1;' would be enough, no? At every recursion level, the number of partitions increases by one. Say conf.partitions starts off at 1. If the routine needs to recurse down a new level, newpartitions is 2, and you will build 2 new Config instances each with '2' as the value for partitions. Recursing down another level, newpartitions is 3, and you build 3 Configs, each with '3' as 'partitions', and so on.
The trick here is to make sure your code is robust enough to avoid infinite recursion.
By the way, it seems inefficient to me to use dynamic allocation for Config instances that have to be destroyed after the loop. Why not build a single Config instance on the stack inside the loop? Your code should run much faster that way.

Dividing each element in a container between a given number C++

I was multiplying each container against another number so I did the following:
local_it begin = magnitudesBegin;
std::advance(begin , 2);
local_it end = magnitudesBegin;
std::advance(end, 14);
std::transform(begin, end, firstHalf.begin(),
std::bind1st(std::multiplies<double>(),100));
It worked wonders, problem is when doing the same to divide between another container. Here is a working example of my problem:
const std::size_t stabilitySize = 13;
boost::array<double,stabilitySize> secondHalf;
double fundamental = 707;
boost::array<double, stabilitySize> indexes = {{3,4,5,6,7,8,9,10,11,12,13,14,15}};
std::transform(indexes.begin(), indexes.end(), secondHalf.begin(),
std::bind1st(std::divides<double>(),fundamental));
It does divide the container. But instead of dividing each element in the array against 707 it divides 707 between each element in the array.
std::bind1st(std::divides<double>(),fundamental)
The code above takes a functor std::divides<double> that takes two arguments and fixes the value of the first argument to be fundamental. That is it fixes the numerator of the operation and you get the expected result. If you want to bind fundamental to be the denominator, use std::bind2nd.
you can try the following , divide has a completely different operation than multiply, it just divides a constant number by all your elements
std::bind1st(std::multiplies<double>(),1.0/707.0));
If the number 707.0 is something like a fundamental constant, and a division can be seen as a "conversion", let's call it "x to y" (I don't know what your numbers are representing, so replace this by meaningful words). It would be nice to wrap this "x to y" conversion in a free-standing function for re-usability. Then, use this function on std::transform.
double x_to_y(double x) {
return x / 707.0;
}
...
std::transform(..., x_to_y);
If you had C++11 available, or want to use another lambda-library, another option is to write this in-line where being used. You might find this syntax more readable like parameter binding using bind2nd:
std::transform(..., _1 / 707.0); // when using boost::lambda