So I'm wondering, how do I make sure that all steps in a loop are performed if the step size is smaller than 1? Take this loop for instance:
for (float y, x = -1.0; x <= 1.0; x += 0.1) {
y = (4*x*x*x) + (3*x*x) + (5*x) - 10;
printf("x = %.2f, y = %.2f\n", x, y);
}
Output:
x = -1.00, y = -16.00
x = -0.90, y = -14.99
x = -0.80, y = -14.13
x = -0.70, y = -13.40
x = -0.60, y = -12.78
x = -0.50, y = -12.25
x = -0.40, y = -11.78
x = -0.30, y = -11.34
x = -0.20, y = -10.91
x = -0.10, y = -10.47
x = 0.00, y = -10.00
x = 0.10, y = -9.47
x = 0.20, y = -8.85
x = 0.30, y = -8.12
x = 0.40, y = -7.26
x = 0.50, y = -6.25
x = 0.60, y = -5.06
x = 0.70, y = -3.66
x = 0.80, y = -2.03
x = 0.90, y = -0.15
I intend the loop to also run for x = 1, but as you can see it doesn't do that. I've heard that it's not safe to use floats as loop counters, as the float precision isn't exact. The fact that I'm using a float variable as the loop counter is probably the cause of my problem. So what solutions are there to my problem? Thanks in advance for your kind responses!
The problem, as you noted, is that you shouldn't use floats as loop counters. So multiply everything by 10 and use integers:
for (int x = -10; x <= 10; ++x) {
float y = (0.004*x*x*x) + (0.03*x*x) + (0.5*x) - 10;
printf("x = %.2f, y = %.2f\n", 0.1*x, y);
}
Produces:
x = -1.00, y = -16.00
x = -0.90, y = -14.99
x = -0.80, y = -14.13
...
x = 0.90, y = -0.15
x = 1.00, y = 2.00
as expected.
Perhaps even better: logically separate your loop variable from the meaningful stuff.
for(int i = -10; i <= 10; ++i) {
float x = 0.1 * i;
float y = (4*x*x*x) + (3*x*x) + (5*x) - 10;
printf("x = %.2f, y = %.2f\n", x, y);
}
Related
I'm trying to optimise a gradient descent of a function using a while loop but the loop doesn't stop. How can I make it works please.
def GradDescent(y, la, nbiter,tau,f,epsilon):
x = y;
crit= np.zeros(nbiter);
xprev = 0
iter = 0
while norm(x-xprev)/norm(x) > epsilon:
xprev = x
x = x - tau*(x - y + la * gradTVeps(x,epsilon))
crit[iter] = 1/2 * (norm(x-y)**2) + la * J(x,epsilon);
iter = 1
return x,crit
nbiter = 10;
epsilon = np.logspace(-5, 0,num=5);
laTVTeq = 0.01;
SNRTVep = 0*np.ones(len(epsilon));
for i in range(0,len(epsilon)):
tau = 1.8/(1 + laTVTeq *4/epsilon[i]);
[xdenoised,crit] = GradDescent( y,laTVTeq, nbiter,tau,f,epsilon[i])
SNRTVep[i] = snr(x0,xdenoised)
Im writing a C code programm that calcultates sine and cosine of a given angle without using the Sine and Cosine Functions of the Math.h library.
But the problem I am facing right now is that i can only calculate the sine and cosine of the Angles between -90° - 90° (so the angles in the first and fourth quadrant). The Cosine(100) = Cosine(80) with a negative operator. So my way of thinking would be to just write code that whenever it gets an angle that is greater than 90 and smaller than 270, it should just substract the additional value from 90; so in the case of Cos(240) that would be the same as Cos(90-150) with an inverted operator infront.
How should one go about this, without having to write 180-if statements?
#include <stdio.h>
#include <math.h>
int main() {
double alpha[29];
alpha[0] = 45.00000000;
alpha[1] = 26.56505118;
alpha[2] = 14.03624347;
alpha[3] = 7.12501635;
alpha[4] = 3.57633437;
alpha[5] = 1.78991061;
alpha[6] = 0.89517371;
alpha[7] = 0.44761417;
alpha[8] = 0.22381050;
alpha[9] = 0.11190568;
alpha[10] = 0.05595289;
alpha[11] = 0.02797645;
alpha[12] = 0.01398823;
alpha[13] = 0.00699411;
alpha[14] = 0.00349706;
alpha[15] = 0.00174853;
alpha[16] = 0.00087426;
alpha[17] = 0.00043713;
alpha[18] = 0.00021857;
alpha[19] = 0.00010928;
alpha[20] = 0.00005464;
alpha[21] = 0.00002732;
alpha[22] = 0.00001366;
alpha[23] = 0.00000683;
alpha[24] = 0.00000342;
alpha[25] = 0.00000171;
alpha[26] = 0.00000085;
alpha[27] = 0.00000043;
alpha[28] = 0.00000021;
double x = 0.60725294;
double y = 0;
double winkel = -150;
double theta = winkel;
double xs;
double ys;
int i = 0;
}
while ( i < 29 ){
printf("This is run number %d with theta = %lf \n", i, theta);
xs = y / pow(2, i);
ys = x / pow(2, i);
if (theta <= 0){
x = x + xs;
y = y - ys;
theta = theta + alpha[i];
} else {
x = x - xs;
y = y + ys;
theta = theta - alpha[i];
};
printf("x = %lf and y = %lf \n \n",x,y);
i++;
}
printf("cosine = %lf\n", x);
printf("sine = %lf\n", y);
return 0;
}
cos(x) = cos(-x)
cos(x) = cos(x%360) if x is in degrees and x is positive
those identities should be sufficient to understand what to do, right?
likewise sin(-x) = -sin(x)
sin(x) = sin(x%360) if x is in degrees and x is positive
Okay, I know the output for the expression (x *= y = z = 4;) is 40; but how exactly did we get 40? Can you please show me step by step.
I thought the precedence is from right to left so (2 * 4) = (z =4), I don't understand
#include <stdio.h>
#define PRINTX printf("%d\n",x)
int main (void){
int x = 2, y, z;
x *= 3 + 2;
PRINTX;
x *= y = z = 4;
PRINTX;
x = y == z;
PRINTX;
x == ( y = z );
PRINTX;
return 0;
}
No, the only way that assignment can be evaluated here is right to left.
First, note that x *= 99, for example, is shorthand for x = x * 99.
With that said,
x *= y = z = 4;
is equivalent to
z = 4;
y = z;
x *= y; // This is shorthand for x = x * 4
Consider what would happen if you tried to evaluate it the other way around:
// y is unininitialized
x *= y;
y = z;
z = 4;
It would fail.
So really,
// x = 2
int x = 2, y, z;
// x = x * (3 + 2) = x * 5 = 2 * 5 = 10
x *= 3 + 2;
// x = x * 4 = 10 * 4 = 40
x *= y = z = 4;
This can be rewritten as
int x, y, z;
x = 2; // x = 2
x = x * (3 + 2); // This is 2 * 5, so x = 10 after this
z = 4; // z = 4
y = z; // y = 4
x = x * y; // x = 10 * 4 = 40
And that's how you end up with 40.
All of the assignment operators have equal precedence, and right-to-left associativity (which affects what happens when multiple operators of equal precedence are present in an expression).
This means x *= y = z = 4 is equivalent to x *= (y = (z = 4)). z = 4 must be evaluated first (which assigns z to 4, and gives a result of 4). The assignment y = ... then gives the value y the value of 4, and also produces a result of 4. The assignment x *= ... then multiples x (which has a value 10) by 4, giving a result of 40.
(The reason x *= 3 + 2 gives x the value 10 is that addition has higher precedence than assignment, so x *= 3+2 is equivalent to x *= (3 + 2) rather than (x *= 3) + 2.)
If the assignment operators were instead left-to-right associative, x *= y = z = 4 would be equivalent to (((x *= y) = y) = z) = 4 which would not compile.
You have:
int x = 2, y, z;
x *= 3 + 2;
This is a shorthand for x = x * (3 + 2), which evaluates to 10 given that x starts at 2.
PRINTX;
x *= y = z = 4;
After this, y == z and both are set to 4; and x is 4 times its previous value of 10, hence 40.
PRINTX;
x = y == z;
This compares y and z; they're equal, so x is assigned 1 (comparisons always evaluate to 0 or 1).
PRINTX;
x == ( y = z );
This assigns z to y (leaving the value unchanged at 4); nominally, this is compared with x but the compiler can ignore the comparison. Therefore, x is unchanged and still 1.
I want to display the values of a function Z = Z(x,y) in the range (x_min, x_max) and (y_min, y_max) using the contourf function in Matlab 2015a. Here is my code:
N = 20;
x_min = 20;
x_max = 40;
y_min = 40;
y_max = 80;
x = linspace(x_min, x_max, N);
y = linspace(y_min, y_max, N);
[X,Y] = meshgrid(y,x);
Z = X.*Y;
for i = 1:N
for j = 1:N
Z(i, j) = 10*i+j;
end
end
contourf(Z);
colorbar
And this is the plot I get:
How can I show the true range of x and y (20<=x=<40 and 40<=y=<80)?
A look at the fantastic MATLAB documentation reveals that you can supply three arguments to contourf, namely the X, Y, and Z values.
N = 20;
x_min = 20;
x_max = 40;
y_min = 40;
y_max = 80;
x = linspace(x_min, x_max, N);
y = linspace(y_min, y_max, N);
[X,Y] = meshgrid(y,x);
Z = X.*Y;
for i = 1:N
for j = 1:N
Z(i, j) = 10*i+j;
end
end
contourf(X,Y,Z);
colorbar
This will give you properly labelled tick marks:
I'm trying to get some formatting done in my sprintf statement, but it doesn't seem to work as I expect. Here is the line:
n = sprintf(buffer, "x = %d.%d, y = %d.%d, z = %d.%d \n", x1, x2, y1, y2, z1, z2);
In that printout x1 is the whole part of the number, and x2 is the fractional part. All would be well, except I need to pad x2, y2, and z2 to always be 2 digits - meaning I need to pad with leading zeros.
With examples that I see online it seems like doing this should work:
n = sprintf(buffer, "x = %d.%02d, y = %d.%02d, z = %d.%02d \n", x1, x2, y1, y2, z1, z2);
However, that instead produces something like this:
x = 2.2d, y = 37.2d, z = 2.2d
The 37 above is actually x2, and it apparently got shifted over in place of y1. I tried putting brackets around the '02', but that doesn't do anything either.
I have tried splitting up the period too like this: (but that didn't work)
n = sprintf(buffer, "x = %d. %02d, y = %d. %02d, z = %d. %02d \n", x1, x2, y1, y2, z1, z2);
I'm not really sure what's wrong... I'd appreciate any help. This isn't particularly vital to do in sprintf (I could theoretically write some 'if' statements and get it working that way), but it'd be nice.
Thanks!
This is a sample code and output.
float x1 = 10.12222;
float y1 = 20.23333;
float z1 = 30.34444;
int xi = 10;
int yi = 20;
int zi = 30;
int x0 = 5;
int y0 = 5;
int z0 = 5;
int xl = 10;
int yl = 10;
int zl = 10;
char chr[512];
printf("x = %5.2f, y = %5.2f, z = %5.2f\n", x1, y1, z1);
printf("x = %10d, y = %10d, z = %10d\n", xi, yi, zi);
printf("x = %010d, y = %010d, z = %010d\n", xi, yi, zi);
printf("x = %-10d, y = %-10d, z = %-10d\n", xi, yi, zi);
printf("x = %10.5d, y = %10.5d, z = %10.5d\n", xi, yi, zi); // DYNAMIC
/* Dynamic formatting of DYNAMIC commented line*/
sprintf(chr, "Dynamic: x = %%%d.%dd, y = %%%d.%dd, z = %%%d.%dd\n",
xl, x0, yl, y0, zl, z0);
printf(chr, xi, yi, zi);
The output will be like this.
x = 10.12, y = 20.23, z = 30.34
x = 10, y = 20, z = 30
x = 0000000010, y = 0000000020, z = 0000000030
x = 10 , y = 20 , z = 30
x = 00010, y = 00020, z = 00030
Dynamic: x = 00010, y = 00020, z = 00030
%x.yd means,
x - Total characters for the integer.
y - Padding with 0s within that length.
%10.5d will give following results for 10, 100, 1000, 10000, 100000, 100000
bbbbbbbbbb => Spaces
00010
00100
01000
10000
100000
1000000
I hope this helps for your formatting.