# Trying to include cblas functions in a new distribution

Hi,

I am writing code for a new distribution and would like to include some functions from blas (I have already got implementations of the distribution and gradients written in a very efficient and robust manner using blas).

At present I am able to compile the new_normal distribution example Stan Math Library: Probability Distributions in a way that I am happy with. As a very minimal working example I have replaced the code to calculate the log density with a very simple function in the file calc_log_like.hpp

``````double calc_log_likelihood(const int n_y, const int n_mu, const int n_sigma, const double* y,const double* mu,const double* sigma){
double l_sum = 0.0;
double y_copy [n_y];

for (int i = 0; i < n_y; ++i){
l_sum += -0.5 * std::pow((y[i] - mu[i]) / sigma, 2);
}
return l_sum;
}
``````

While this code isn’t very general (it only works when mu and y are vectors of same length and sigma is a scalar it does let me test what I want. I can do

``````#include "calc_log_like.hpp"
``````

inside new_normal.hpp and call the function to calculate the log density. This compiles and works fine during sampling.

Next, the simplest test of using a blas function I could think of was to use the dcopy() so I modified my function to be

``````extern "C"
{
#include <cblas.h>
}

double calc_log_likelihood(const int n_y, const int n_mu, const int n_sigma, const double* y,const double* mu,const double* sigma){
double l_sum = 0.0;
double y_copy [n_y];

cblas_dcopy(n_y, y, 1, y_copy, 1);

for (int i = 0; i < n_y; ++i){
l_sum += -0.5 * std::pow((y_copy[i] - mu[i]) / sigma, 2);
}
return l_sum;
}
``````

I then use the make/local file with the following line

``````CXXFLAGS+= -L /usr/lib/x86_64-linux-gnu/atlas/ -lcblas
``````

I am using ubuntu and have used apt-get install libatlas-base-dev to get blas

When I try to compile the model file I get the error

``````in function `calc_log_likelihood(int, int, int, double const*, double const*, double const*)':
ssm.hpp:(.text+0x430): undefined reference to `cblas_dcopy'
``````

How can I link the blas functions correctly?

``````LDFLAGS+= -lcblas
``````

If you’ve installed ATLAS through `apt` then the library and its objects should already be in the path that the compiler checks, so you don’t need to manually specify the path to the library (I think)

Thanks for the fast response.

``````LDFLAGS+= -lcblas
``````

below the CXXFLAGS line in make/local? I tried doing that with both -lblas and -lcblas and neither option worked. Also tried leaving in

``````CXXFLAGS+= -L /usr/lib/x86_64-linux-gnu/atlas/
``````

In case that was required. If that should have worked, any other ideas what I might need to do?

Ah I was close but a little off, it’s `LDLIBS`, not `LDFLAGS`:

``````LDLIBS += -lcblas
``````

That did the trick. Thank you very much. Also, you were correct and I did not need to specify the path to the library.

1 Like