How to build a MEX-file in MATLAB? - c

I need to use the following function in MATLAB code:
#include "mex.h"
#include <math.h>
#include <stdio.h>
float xFit_1931( float wave )
{
float t1 = (wave-442.0f)*((wave<442.0f)?0.0624f:0.0374f);
float t2 = (wave-599.8f)*((wave<599.8f)?0.0264f:0.0323f);
float t3 = (wave-501.1f)*((wave<501.1f)?0.0490f:0.0382f);
return 0.362f*expf(-0.5f*t1*t1) + 1.056f*expf(-0.5f*t2*t2)
- 0.065f*expf(-0.5f*t3*t3);
}
float yFit_1931( float wave )
{
float t1 = (wave-568.8f)*((wave<568.8f)?0.0213f:0.0247f);
float t2 = (wave-530.9f)*((wave<530.9f)?0.0613f:0.0322f);
return 0.821f*exp(-0.5f*t1*t1) + 0.286f*expf(-0.5f*t2*t2);
}
float zFit_1931( float wave )
{
float t1 = (wave-437.0f)*((wave<437.0f)?0.0845f:0.0278f);
float t2 = (wave-459.0f)*((wave<459.0f)?0.0385f:0.0725f);
return 1.217f*exp(-0.5f*t1*t1) + 0.681f*expf(-0.5f*t2*t2);
}
This function is coded in C language so I tried to build a MEX-file but I got this error message:
>> mex CMfunction.c
Building with 'lcc-win32'.
Error using mex
c:\users\ya7yawii\appdata\local\temp\mex_1695753636261_3832\cmfunction.obj
.text: undefined reference to '_expf'
Specified export _mexFunction is not defined
Missing exports. Aborting

I have just rewritten these functions in matlab code using the mathematical equations in the following paper Simple Analytic Approximations to the CIE XYZ
Color Matching Functions.
function int = xFit_1931(wave)
t1 = 0.0624.*(1-heaviside(wave-442.0))+0.0374.*heaviside(wave-442.0);
t2 = 0.0264.*(1-heaviside(wave-599.8))+0.0323.*heaviside(wave-599.8);
t3 = 0.0490.*(1-heaviside(wave-501.1))+0.0382.*heaviside(wave-501.1);
int = 0.362.*exp(-0.5.*((wave-442.0).*t1).^2)+1.056.*exp(-0.5.*((wave-599.8).*t2).^2)-0.065.*exp(-0.5.*((wave-501.1).*t3).^2);
end
function int = yFit_1931(wave)
t1 = 0.0213.*(1-heaviside(wave-568.8))+0.0247.*heaviside(wave-568.8);
t2 = 0.0613.*(1-heaviside(wave-530.9))+0.0322.*heaviside(wave-530.9);
int = 0.821.*exp(-0.5.*((wave-568.8).*t1).^2)+0.286.*exp(-0.5.*((wave-530.9).*t2).^2);
end
function int = zFit_1931(wave)
t1 = 0.0845.*(1-heaviside(wave-437.0))+0.0278.*heaviside(wave-437.0);
t2 = 0.0385.*(1-heaviside(wave-459.0))+0.0725.*heaviside(wave-459.0);
int = 1.217.*exp(-0.5.*((wave-437.0).*t1).^2)+0.681.*exp(-0.5.*((wave-459.0).*t2).^2);
end

Related

How do I fix/debug a "lvalue required as left operand of assignment" error?

I'm very new to coding. I'm trying to make a simple math equation making use of float, using this code:
#include <stdio.h>
#include <math.h>
int car() {
int r1;
int m1;
int m2;
float lift_a_car(const int r1, const int m1, const int m2);
lift_a_car = r1 + (2 * m1 / (m1 + m2));
printf("%.4f\n", lift_a_car(2, 80, 1400));
return 0;
}
Whenever I run it, I get this error:
arrays.c:12:12: error: lvalue required as left operand of assignment
12 | lift_a_car = r1 + (2 * m1 / (m1 + m2));
I couldn't find a good explanation for this error anywhere. Can someone please explain this error to me? And is there any way to simplify/improve this code overall?
Try something like that:
#include <stdio.h>
#include <math.h>
// functions shall be defined here
float lift_a_car(int r1, int m1, int m2)
{
// note to get a float result, you need to cast to float
return (r1 + (2 * (float)m1 / (m1 + m2)));
}
int main() {
// Here you can call the function
printf("%.4f\n", lift_a_car(2, 80, 1400));
return 0;
}
lift_a_car is a function and you cannot assign to a function in C. If you wanted to define a function, you should specify a function body using curly braces:
float lift_a_car(const int r1, const int m1, const int m2)
{
return r1 + (2 * m1 / (m1 + m2));
}
Note that you cannot define a function inside of another function in C, so your lift_a_car function must be defined outside and before your car function.
It seems like you want to create a function lift_a_car. It must be outside of int car as nested functions are not supported. Functions must be top-level entities in C, not within any scope ({}). (In your code, lift_a_car is inside car). And the name of the entry-point function must be main. Since your car function returns 0, it seems like you are trying to use car instead of the name main :
#include <stdio.h>
#include <math.h>
float lift_a_car(const int r1, const int m1, const int m2)
{
float result = r1 + (2 * m1 / (m1 + m2));
return result;
}
int main()
{
int r1 = 2;
int m1 = 80;
int m2 = 1400;
printf("%.4f\n", lift_a_car(r1, m1, m2));
return 0;
}
Also, since you are performing division with two integers, the decimal points will be truncated, so cast one of the values first to float to retain the decimal points:
float lift_a_car(const int r1, const int m1, const int m2)
{
float result = r1 + ((float) 2 * m1 / (m1 + m2));
return result;
}
We could try to help more if you provide more details about what you are trying to do.

C pass value to matlab and get result from it

I'm working with C program, and have a simple C code to generate data like follow:
#include <stdio.h>
#include <time.h>
#include <math.h>
double x[100];
int i;
srand(3);
for (i = 0; i < 100; i++)
{
x[i] = (double) rand() / (RAND_MAX + 1.0);
}
I want to pass this array into matlab, and do the following calculate:
y = transpose(x)
Mdl = arima(1,0,0)
[EstMdl,EstParamCov,logL,info] = estimate(Mdl,y)
a = EstMdl.AR
b = EstMdl.Variance
How can I pass array x to matlab and get a and b back from matlab using C language?
Thanks in advance.

MPI Program null pointer

I am trying to create an mpi program that will run my bellard function to calculate pi to ten thousand decimal places. When i run the program i am presented with the following errors, I have done some searching online and on the openMpi website, the problem appears to be a null pointer but i have looked through the code and cant seem to find it.
The error is:
Signal :segmentation fault(11)
Signal :address not mapped(1)
Failing at address : (nil)
Can anyone see the null pointer ?
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <mpi/mpi.h>
#define PRECISION 10000
float minus_one,one,two,three,four,five,six,seven,eight,nine,ten,
thirty_two,sixty_four,two_five_six,one_zero_two_four,
two_pow_six,recip_two_pow_six;
float *pi;
int rank,size;
void init(){
printf("\nstarted init function");
minus_one = -1.0;
one = 1.0;
two = 2.0;
three = 3.0;
four = 4.0;
five = 5.0;
six = 6.0;
seven = 7.0;
eight = 8.0;
nine = 9.0;
ten = 10.0;
thirty_two = 32.0;
sixty_four = 64.0;
two_five_six = 256.0;
one_zero_two_four = 1024.0;
two_pow_six = pow(two,6);
recip_two_pow_six = one/two_pow_six;
pi = 0;
printf("\nended init function");
return;
}
float *bellard(int start, int end,int rank){
float *terms;
float t,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,
t13,t14,t15,t16,t17,tx,ty,tz;
int offset = rank;
double start_k = start;
double end_k = end;
start_k = offset * (PRECISION /size);
end_k = (offset+1) * (PRECISION/size);
terms=0;
int k = start_k;
while( (k<PRECISION) && (k<end_k)){
t1 = k;
t2 = t1*ten;
t3 = t2+one;
t4 = two_five_six/t3;
t5 = t2+nine;
t6 = one/t5;
t7 = t2+three;
t8 = sixty_four/t7;
t9 = four*t1;
t10 = t9+one;
t11 = thirty_two/t10;
t12 = t2+five;
t13 = four/t12;
t14 = t2+seven;
t15 = four/t14;
t16 = t9+three;
t17 = one+t16;
t = t4+t6;
t = t-t8;
t = t-t11;
t = t-t13;
t = t-t15;
t = t-t17;
tx = pow(minus_one,k);
ty = pow(one_zero_two_four,k);
tz = tx/ty;
*terms = tz*t;
//pi = pi+terms;
k = k+1;
}
return terms;
}
int main(int argc, char** argv){
int i;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int elementsCount = 10000/(size-1);
float *workerPi;
float *tmpPi=0;
init(); //initialise variables
printf("\nim here 1");
if(rank == 0)
{
for(i=1; i < size; i++){
printf("\nin recv loop");
MPI_Recv(tmpPi,PRECISION,MPI_FLOAT,i,1,MPI_COMM_WORLD,&status);
*pi=*pi+*tmpPi;
}
}else{
//int i;
int start,end,slice,workers;
workerPi = malloc(sizeof(int)*elementsCount);
workers = size-1;
slice = 10000/workers;
start = (rank-1)*slice;
end = start+slice;
printf("\nWorker %d processing data %d to %d\n",rank,start,end);
workerPi = bellard(start,end,rank);
printf("\nworker finished pi");
MPI_Send(workerPi,slice,MPI_FLOAT,0,1,MPI_COMM_WORLD);
printf("\nworker sent stuff");
}
MPI_Finalize();
return 0;
}
In the bellard function, terms is declared as a pointer to float
float *terms;
and initialized to zero (aka null) a few lines down
terms=0;
Towards the end of the while loop, it is dereferenced:
*terms = tz*t;
The statement *terms is a null pointer dereference and will crash. It is essentially asking to store the result of tz*t into memory address zero, which is not a valid memory address.
The fix may be to declare and use terms as a float, not a pointer to a float (float*).

Accessing variable by pointer in OpenCL kernel

I am writing a raytracing program in OpenCL and I have a function in my Kernel, Quadratic, that takes in 3 float variables and two pointers to float values.
Function:
bool Quadratic(float A, float B, float C, float *t0, float *t1) {
float discrim = B * B - ( 4.0 * A * C );
if (discrim <= 0.0) return false;
float rootDiscrim = sqrtf(discrim);
float q;
if (B < 0) q = -0.5f * ( B - rootDiscrim);
else q = -0.5f * ( B + rootDiscrim);
*t0 = q / A;
*t1 = C / q;
float temp;
return true;
}
Calling the Function:
float t0;
float t1;
if (Quadratic(A, B, C, &t0, &t1)) c[(i*dimy)+j] = t0;
else c[(i*dimy)+j] = 0.0;
Produces the following error:
pyopencl.RuntimeError: clBuildProgram failed: build program failure -
Build on <pyopencl.Device 'ATI Radeon HD 6750M' on 'Apple' at 0x1021b00>:
Error returned by cvms_element_build_from_source
In trying to work out what the problem was I created the following test function which seems to work:
bool TestFunc(float Y, float *x) {
*x = Y;
return true;
}
float x;
if (TestFunc(50.0, &x)) c[(i*dimy)+j] = x;
As far as I can see both functions have the same types of inputs and outputs, any help would be greatly appreciated.
It turns out the problem was with using sqrtf. Once changed to sqrt it works perfectly.

Using cos() function in a for loop gets undefined reference to cos error [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C Build error when getting the value of sin()
I am trying to integrate a function using 100 intervals within the period, so I'm using a for loop. The function contains cos(stuff here), but it won't run within the for loop for some reason. If I move it out of the for loop, it works fine. I have #include , so I don't understand. Any help is appreciated. Thanks.
#include <stdio.h>
#include <math.h>
//float t = 0.000000;
double T = .001;
int n = 100;
double pi = 3.141592654;
double a[5];
double b[5];
double function_results[100];
double anfunction_results[100];
double bnfunction_results[100];
double final = 0.000000000000;
double anfinal = 0.000000000;
double k = 0.000000;
double function(float t){
double f = 3*pow(t,2);
return f;
}
int main()
{
//double w = 2*pi/T;
double h = T/n;
int i = 1;
for(; i<100; i++){
double iterate = -T/2 + h*i;
function_results[i] = function(iterate);
final = final + function_results[i];
}
a[0] = (h/3)*(function(-T/2) + final+function(T/2))/T;
printf("%.12f \n",a[0]);
int p = 1;
int l = 1;
for(; l<=5; l++){
for(; p<100; p++){
double iteration = -T/2 + h*p;
k = l+.0000001;
anfunction_results[p] = 3*pow(iteration,2)*cos(k*iteration*2.00000*pi/T*pi/180.00000);
anfinal = anfunction_results[p] + anfinal;
}
a[l] = (2/T)*(h/3)*(3*pow(-T/2,2)*cos(-T/2.0000) + anfinal + 3*pow(T/2,2)*cos(k*T/2.00000*2.00000*pi/T*pi/180.00000));
}
//printf("%.12f \n",a[1]);
//printf("%.12f \n",a[2]);
//printf("%.12f \n",a[3]);
//printf("%.12f \n",a[4]);
//printf("%.12f \n",a[5]);
return 0;
}
You are probably not linking to the math library. Add -lm to your linker options.
(I don't know why it would "run fine" with cos() moved out of the for loop, but this explanation is not very clear on your part. If you get an undefined reference for cos() in one part of the program, you should get it in a different part as well, if the compiler options are the same in both cases.)

Resources