C: Multidimensional array implementatio not working, giving different values - c

I am trying to implement a multidimensional array. Below, you will see for one example in jArray[2][2] that I assign 20.0, clearly. However, both printf statements don't yield the same result. Thanks for your help!
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define M_PI 3.14159265358979323846
int main(){
float x1 = 0.1;
float x2 = 0.1;
float x3 = -0.1;
float jArray [3][3] = {
{3.0, x3*sin(x2*x3), x2*sin(x2*x3)},
{2*x1, -162*(x2+0.1), cos(x3)},
{-x2*exp(-x1*x2), -x1*exp(x1*x2), 20.0}
};
float matrix0 [3][3] = {
{jArray[0][0], jArray[0][1], jArray[0][2]},
{jArray[1][0], jArray[1][1], jArray[1][2]},
{jArray[2][0], jArray[2][1], jArray[2][2]},
};
printf("%f\n\n", jArray[2][2]);
printf("[%f\t%f\t%f]\n[%f\t%f\t%f]\n[%f\t%f\t%f]\n\n",
matrix0[0][0], matrix0[0][1], matrix0[0,2],
matrix0[1][0], matrix0[1][1], matrix0[1,2],
matrix0[2][0], matrix0[2][1], matrix0[2,2]);
return 1;
}
Output:
20.000000
[3.000000 0.001000 0.200000]
[-32.400002 -0.099005 -0.101005]
[0.000000 0.010000 0.000000]

Replace
printf("[%f\t%f\t%f]\n[%f\t%f\t%f]\n[%f\t%f\t%f]\n\n",
matrix0[0][0], matrix0[0][1], matrix0[0,2],
matrix0[1][0], matrix0[1][1], matrix0[1,2],
matrix0[2][0], matrix0[2][1], matrix0[2,2]);
with
printf("[%f\t%f\t%f]\n[%f\t%f\t%f]\n[%f\t%f\t%f]\n\n",
matrix0[0][0], matrix0[0][1], matrix0[0][2],
matrix0[1][0], matrix0[1][1], matrix0[1][2],
matrix0[2][0], matrix0[2][1], matrix0[2][2]);
Your compiler would've emitted a warning for that because %f expects a float(or a double), not a float*.

Related

Why am I getting 0 as the output? Can you find the mistake?

The problem is about inputting two sides and the included angle for 6 different triangular plots. We need to find the area of each of these plots.
I wrote this code using 2-D and 1-D arrays and passing the 2-D array to a void function which prints the areas of each of the plots. These are the inputs and their respective outputs I got. I am using Ubuntu 18.04 LTS Terminal.
RUN OF THE PROGRAM
Input:
1
137.4
80.9
0.78
2
155.2
92.62
0.89
3
149.3
97.93
1.35
4
160.0
100.25
9.00
5
155.6
68.95
1.25
6
149.7
120.0
1.75
Output:
Entered Data is:
1.000000 137.399994 80.900002 0.780000
2.000000 155.199997 92.620003 0.890000
3.000000 149.300003 97.930000 1.350000
4.000000 160.000000 100.250000 9.000000
5.000000 155.600006 68.949997 1.250000
6.000000 149.699997 120.000000 1.750000
Area of plot 1 is: 0.000000.
Area of plot 2 is: 0.000000.
Area of plot 3 is: 0.000000.
Area of plot 4 is: 0.000000.
Area of plot 5 is: 0.000000.
Area of plot 6 is: 0.000000.
Program:
#include <stdio.h>
#include <math.h>
void area(float p[6][4],int m,int n);
int main()
{
float a[6][4];
int i,j;
printf("Enter the plot no.,two sides and included angle.\n");
for(i=0;i<6;i++)
{
for(j=0;j<4;j++)
{
scanf("%f",&a[i][j]);
}
}
printf("Entered Data is:\n");
for(i=0;i<6;i++)
{
for(j=0;j<4;j++)
{
printf("%f ",a[i][j]);
}
printf("\n");
}
printf("\n");
area(a,6,4);
return 0;
}
void area(float p[6][4],int m,int n)
{
float ar[6];
int i;
for(i=0;i<6;i++)
{
ar[i] = (1/2)*(p[i][1])*(p[i][2])*sin(p[i][3]);
printf("Area of plot %d is: %f.\n",i+1,ar[i]);
}
}
In this expression:
ar[i] = (1/2)*(p[i][1])*(p[i][2])*sin(p[i][3]);
(1/2) evaluates as zero, which means the whole thing comes out as zero (because zero times anything is zero). The reason for it being zero is because it's integer division, which gives a truncated integer as its result. Use 0.5 instead.
(1.0/2.0) * (p[i][1]) * (p[i][2]) * sin(p[i][3]);

Can't implement square root systemcall in linux kernel

I need to implement this function as a systemcall:
asmlinkage ​ long​​ sys_sqrt (​ float​ x);
Where the function gonna print the square root of n to the kernel log.
I'm using kernel version 4.13 on 64bit virtual box.
I'm trying to implement the sqrt by using this technique
#include <linux/kernel.h>
#define SQRT_MAGIC_F 0x5f3759df
asmlinkage ​long​​ sys_sqrt(​float​ x);
{
const float xhalf = 0.5f*x;
union // get bits for floating value
{
float x;
int i;
} u;
u.x = x;
u.i = SQRT_MAGIC_F - (u.i >> 1);
printk ("%f", (x*u.x*(1.5f - xhalf*u.x*u.x));
return 0;
}
This leads the compiler telling me "error: SSE register return with SSE disabled" on "printk ("%f", (x * u.x * (1.5f - xhalf * u.x * u.x));"
Another workaround I tried is separating the integer and the decimals like so
float ans = (x*u.x*(1.5f - xhalf*u.x*u.x);
int head = ans;
float tail_float = ans - head;
int tail = tail_float*10000;
printk ("%d.%03d", head,tail);
This leads the compiler telling me "error:SSE register return with SSE disabled" on "float ans = (x *u.x *(1.5f - xhalf * u.x* u.x);"
another thing i've tried is adding a kernel_fpu_begin & end between the function body but this leads "error: implicit declaration of function "kernel_fpu_begin"; did you mean "kernel_old_dev_t"
Any solution?
Thank you so much.

Using SSE effectively for rasterization

I've been thinking about using the SSE instruction set to make my 3d software rasterizer faster, but I've never used them before and feel like I am going completely wrong.
I'd like to hear from the more experienced on whether it is an effort that is worth it, and if this code is written poorly:
typedef union _declspec(align(16)) {
struct {
float x;
float y;
float z;
float w;
};
__m128 m128;
} Vec4_t;
Vec4_t AddVec(Vec4_t* a, Vec4_t *b) {
__m128 value = _mm_add_ps(a->m128, b->m128);
return *(Vec4_t*)&value;
}
This is how I'm testing it:
Vec4_t a = { 2.0f, 4.0f, 10.0f, 123.1f };
Vec4_t b = { 6.0f, 12.0f, 16.0f, 64.0f };
Vec4_t c = AddVec(&a, &b);
printf("%f, %f, %f, %f\n", c.x, c.y, c.z, c.w);
which outputs:
8.000000, 16.000000, 26.000000, 187.100006
I honestly have no idea what I'm doing. I'm surprised the code I wrote even worked.

Functions and floating point comparison

#include<stdio.h>
#include<stdlib.h>
#define abs(a) ((a)>0 ? a: -a)
#define eps_sqrt 0.00000000000001
#define it 100
float sqrt(float x)
/*The Square Root Function using the Newton's Method*/
{
int it_sqrt=0;
float a_sqrt = x/2;
while ((abs((a_sqrt*a_sqrt)-(x))>=eps_sqrt) && (2.0*a_sqrt != 0) && (it_sqrt<=it))
{
a_sqrt = a_sqrt - ((a_sqrt*a_sqrt)-(x)/(2.0*a_sqrt));
it_sqrt++;
}
return a_sqrt;
}
int main()
{
printf("%.5f\n", sqrt(5));
system ("pause");
}
i tried using the Newton's iteration method to find the square root on Python and it worked, perfectly well.
I'm new on C and I don't understand why this function didn't work for me.
Whenever I run it, it returns "-1.#INF0A"
Any help will be appreciated.
Edit: I tried changin the eps to 0.000001 and it also didn't work.
Changing this line:
a_sqrt = a_sqrt - ((a_sqrt*a_sqrt)-(x)/(2.0*a_sqrt));
to
a_sqrt = a_sqrt - ((a_sqrt*a_sqrt - x)/(2.0*a_sqrt));
works for me.
Try to use a bigger epsilon, maybe python uses doubles instead of floats.
double mysqrt(double x){
double eps=pow(10,-10);
double x0 = 0.0;
double x1 = x/2.0;
while(fabs(x1 - x0)>eps){
x0 = x1;
x1 = x0 + (x - x0*x0)/x0/ 2.0;
}
return x1;
}
macro expansion
abs((a_sqrt*a_sqrt)-(x))
expansion (((a_sqrt*a_sqrt)-(x))>0 ? (a_sqrt*a_sqrt)-(x): -(a_sqrt*a_sqrt)-(x))
NG: -(a_sqrt*a_sqrt)-(x)
abs((a_sqrt*a_sqrt- x))
expansion (((a_sqrt*a_sqrt- x))>0 ? (a_sqrt*a_sqrt- x): -(a_sqrt*a_sqrt- x))
rewrite
#define abs(a) ((a)>0 ? a: -a)
to
#define abs(a) ((a)>0 ? a: -(a))
This is one of the rare cases where using double actually makes sense.
Note that the precision of float is significantly lower than eps_sqrt:
[mic#mic-nb tmp]$ cat tmp2.c
#include <stdio.h>
#include <math.h>
int main() {
double a = sqrtl(2.0);
printf("%1.20f\n", a - (float) a);
}
[mic#mic-nb tmp]$ gcc tmp2.c; ./a.out
0.00000002420323430563
vs. your value of:
0.00000000000001
So your program will, in most cases, never terminate.

Getting p-value for linear regression in C gsl_fit_linear() function from GSL library

I'm trying to reporduce some code from R in C, so I'm trying to fit a linear regression using the gsl_fit_linear() function.
In R I'd use the lm() function, which returns a p-value for the fit using this code:
lmAvgs<- lm( c(1.23, 11.432, 14.653, 21.6534) ~ c(1970, 1980, 1990, 2000) )
summary(lmAvgs)
I've no idea though how to go from the C output to a p-value, my code looks something like this so far:
int main(void)
{
int i, n = 4;
double x[4] = { 1970, 1980, 1990, 2000 };
double y[4] = {1.23, 11.432, 14.653, 21.6534};
double c0, c1, cov00, cov01, cov11, sumsq;
gsl_fit_linear (x, 1, y, 1, n, &c0, &c1, &cov00, &cov01, &cov11, &sumsq);
}
This seems to correctly calculate slope and intercept but I don't know how to get a p-value. I'm novice at stats and C!
Everything is on : http://en.wikipedia.org/wiki/Ordinary_least_squares. but here is a piece of code which display an output similar to summary(lmAvgs) in R. To run this, you need the GSL Library :
int n = 4;
double x[4] = { 1970, 1980, 1990, 2000};
double y[4] = {1.23, 11.432, 14.653, 21.6534};
double c0, c1, cov00, cov01, cov11, sumsq;
gsl_fit_linear (x, 1, y, 1, n, &c0, &c1, &cov00, &cov01, &cov11, &sumsq);
cout<<"Coefficients\tEstimate\tStd. Error\tt value\tPr(>|t|)"<<endl;
double stdev0=sqrt(cov00);
double t0=c0/stdev0;
double pv0=t0<0?2*(1-gsl_cdf_tdist_P(-t0,n-2)):2*(1-gsl_cdf_tdist_P(t0,n-2));//This is the p-value of the constant term
cout<<"Intercept\t"<<c0<<"\t"<<stdev0<<"\t"<<t0<<"\t"<<pv0<<endl;
double stdev1=sqrt(cov11);
double t1=c1/stdev1;
double pv1=t1<0?2*(1-gsl_cdf_tdist_P(-t1,n-2)):2*(1-gsl_cdf_tdist_P(t1,n-2));//This is the p-value of the linear term
cout<<"x\t"<<c1<<"\t"<<stdev1<<"\t"<<t1<<"\t"<<pv1<<endl;
double dl=n-2;//degrees of liberty
double ym=0.25*(y[0]+y[1]+y[2]+y[3]); //Average of vector y
double sct=pow(y[0]-ym,2)+pow(y[1]-ym,2)+pow(y[2]-ym,2)+pow(y[3]-ym,2); // sct = sum of total squares
double R2=1-sumsq/sct;
cout<<"Multiple R-squared: "<<R2<<", Adjusted R-squared: "<<1-double(n-1)/dl*(1-R2)<<endl;
double F=R2*dl/(1-R2);
double p_value=1-gsl_cdf_fdist_P(F,1,dl);
cout<<"F-statistic: "<<F<<" on 1 and "<<n-2<<" DF, p-value: "<<p_value<<endl;
Which gives :
Coefficients Estimate Std. Error t value Pr(>|t|)
Intercept -1267.91 181.409 -6.98922 0.0198633
x 0.644912 0.0913886 7.05681 0.0194956
Multiple R-squared: 0.961389, Adjusted R-squared: 0.942083
F-statistic: 49.7986 on 1 and 2 DF, p-value: 0.0194956
R gives :
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -1.268e+03 1.814e+02 -6.989 0.0199 *
c(1970, 1980, 1990, 2000) 6.449e-01 9.139e-02 7.057 0.0195 *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 2.044 on 2 degrees of freedom
Multiple R-squared: 0.9614, Adjusted R-squared: 0.9421
F-statistic: 49.8 on 1 and 2 DF, p-value: 0.01950

Resources