Потому что вы делите на 0.
Запишите
assert(a[k][i] != 0);
перед
float s = a[k + 1][i] / a[k][i];
и убедитесь в этом сами…
Что и неудивительно — ведь матрица
10 23 17 44
15 35 26 69
25 57 42 108
30 69 51 133
вырожденная, ее определитель равен 0…
P.S. Что-то странный у вас вложенный цикл
for (int i = 0; i < n-1; i++) {
for (int i = 0; i < n - 1; i++) {
нет? i
во вложенном цикле скрывает i
из внешнего, да и дальнейшее вызывает сомнения… int z = a[i][y];
тоже как-то не комильфо — зачем double
до int
обрезать?
Но главное — какой смысл в проверках до преобразований? Ведь именно в их процессе очередной опорный элемент может стать нулевым! Возьмите простую матрицу, типа
1 1
1 1
и вручную убедитесь, что первая ваша проверка работает, но уже после первой итерации преобразований вы получите нулевую вторую строку — и никаких проверок такой неприятности у вас уже нет.
- Remove From My Forums
-
Question
-
So I’m writing a code to solve for the two angles and missing side of a right triangle. The code has no errors and solves for my side («c») perfectly. However for the angles it prints out -nan(ind). I have been in this class for a total of maybe
5 class meetings so i don’t know what is going on or how to fix it. So if anyone can plainly explain the issue as though i have no clue what any of the C++ terminology actually is. lol! thank you. Any help is great otherwise just don’t.Here is the code:
#include <iostream>;
#include <cmath>;
using namespace std;
int main()
{
long double a, b, c, A, A1, B1, B, tot1, tot2, tot3;
char done, an;
cout << «input value of a n»;
cin >> a;
cout << «input value of b n»;
cin >> b;
tot1 = a*a + b*b;
c = sqrt(tot1);
cout << «c=» << c <<«n»;
tot2 = (b*b + c*c — a*a) / 2 * b*c;
A1 = acos(tot2);
A = A1 * 180 / 3.14;
cout << A << «n»;
cin >> done;
tot3 = (a*a + c*c — b*b) / 2 * a*c;
B1 = acos(tot3);
B = B1 * 180 / 3.14;
cout << B << «n»;
cin >> done;
cout << «C is equal to 90 degrees n «;
system(«pause»);
return 0;};
Answers
-
tot2 = (b*b + c*c — a*a) / 2 * b*c;
A1 = acos(tot2);Your formula for tot2 is incorrect. You are missing a set of parentheses around the divisor.
-
Proposed as answer by
Monday, February 15, 2016 9:21 AM
-
Marked as answer by
May Wang — MSFT
Wednesday, February 17, 2016 8:16 AM
-
Proposed as answer by
-
Hi,
I had test the code, we can reproduce the issue. In order to solve issue. you should do it :
tot2 = ((b*b + c*c — a*a) /( 2 * b*c));
Best Regards,
Hart
-
Proposed as answer by
Hart Wang
Monday, February 15, 2016 9:21 AM -
Marked as answer by
May Wang — MSFT
Wednesday, February 17, 2016 8:16 AM
-
Proposed as answer by
- Forum
- Beginners
- -nan(ind)?
-nan(ind)?
So I’m writing a program that demonstrates Newton’s method to find a root of an equation. It outputs the estimated value of the root, the the true error and empirical error. After trying to run the program, the true error and estimated error were outputting «-nan(ind)». I stepped through my program and found out that the original function for Newton’s method was returning this «-nan(ind)». What is «-nan(ind)» and how do I avoid it in this program?
|
|
NaN is «not a number», possibly resulting from some mathematical faux pas like dividing by 0, or using something undefined. Difficult to tell without full code.
You appear to be implementing the bisection method, not the Newton(-Raphson) method for root-finding. I would expect to see the latter involving a function and its derivative, not your «empirical error».
Can we see your equation( ) function, please: the function whose root you are trying to find.
Also note that your newton function won’t know what to return if equation(cval) is exactly equal to 0 — which, of course, is the root you are seeking.
Is there any reason you are using recursion rather than the more straightforward iteration?
Last edited on
|
|
Here’s the code for the equation and it’s first derivative. I’m using recursion even though it’s less straightforward because I honestly need more practice in recursion and this gave me a great excuse to try it.
I also tried implementing a condition for equation == 0, but the same problem is still happening
Your original routine newton( ) — your original post — does not return ANYTHING unless count = 20.
To remedy this, simply insert
return estroot;
at the end of this function (between lines 23 and 24 in your original post).
When I checked it, your program then worked.
There are multiple potential problems with your approach.
— Just change your original line 19 to plain
else
Then at least one option will be followed.
— Your method is BISECTION and not NEWTON-RAPHSON (aka Newton’s method).
— It would be far better done by iteration than recursion.
— You don’t check that your original aval and bval actually span the root.
— dividing by the derivative in line 39 will fail for many functions (e.g. y = (x-2)cubed), where the root also has zero slope.
Topic archived. No new replies allowed.
Написал функцию поворота прямой.
// Line - y = _k * x + _b
void Line::rotation(double angle) {
double temp = _k;
_k = (_k + tan(angle))/(1 - _k*tan(angle));
_b *= _k/temp;
}
double Line::rotationAngle(const Line &l) { // counterclock-wise from l to this
return atan((_k - l._k)/(1. + _k*l._k));
}
При вводе следующих данных
Line Line1(0, 0), Line2(2, 1);
cout << Line1;
cout << Line2;
Line1.rotation(Line2.rotationAngle(Line1));
cout << Line1;
Почему-то выдает следующее
y = 0x + 0
y = 2x + 1
y = 2x + -nan(ind)
Коэффициент повернутой прямой программа посчитала правильно (_k = 2), но почему-то потом не может поделить 2 на 2:_b *= _k/temp;
Хотя если temp заменить 2, то все ок. Выдаст: y = 2x + 0
Вроде бы никаких корней и делений на ноль. В чем причина?
By using complex math it is possible … The problem is that the pow
is using ln
operation which is on complex domain multi-valued which means it has infinite number of valid result (as imaginary part of result is added with k*2*PI
where k
is any integer). So when the used result is not added with correct k
then the result will be complex and not the one you want.
However for rooting (1.0/exponent -> integer) the k
can be obtained directly as this:
int k=int(floor((1.0/exponent)+0.5))/2;
Which I discovered just now empirically. When I rewrite my complex math cpow
to use this I got this C++ code:
//---------------------------------------------------------------------------
vec2 cadd(vec2 a,vec2 b) // a+b
{
return a+b;
}
vec2 csub(vec2 a,vec2 b) // a-b
{
return a-b;
}
vec2 cmul(vec2 a,vec2 b) // a*b
{
return vec2((a.x*b.x)-(a.y*b.y),(a.x*b.y)+(a.y*b.x));
}
vec2 cdiv(vec2 a,vec2 b) // a/b
{
float an=atan2(-a.y,-a.x)-atan2(-b.y,-b.x);
float r=length(a)/length(b);
return r*vec2(cos(an),sin(an));
}
vec2 csqr(vec2 a) // a^2
{
return cmul(a,a);
}
vec2 cexp(vec2 a) // e^a
{
// e^(x+y*i)= e^x * e^(y*i) = e^x * ( cos(y) + i*sin(y) )
return exp(a.x)*vec2(cos(a.y),sin(a.y));
}
vec2 cln(vec2 a) // ln(a) + i*pi2*k where k={ ...-1,0,+1,... }
{
return vec2(log(length(a)),atan2(a.y,a.x));
}
vec2 cpow(vec2 a,vec2 b) // a^b
{
return cexp(cmul(cln(a),b));
}
vec2 ctet(vec2 a,int b) // a^^b
{
vec2 c=vec2(1.0,0.0);
for (;b>0;b--) c=cpow(a,c);
return c;
}
//-------------------------------------------------------------------------
vec2 cln(vec2 a,int k) // ln(a) + i*pi2*k where k={ ...-1,0,+1,... }
{
return vec2(log(length(a)),atan2(a.y,a.x)+float(k+k)*M_PI);
}
float mypow(float a,float b) // a^b
{
if (b<0.0) return 1.0/mypow(a,-b);
int k=0;
if ((a<0.0)&&(b<1.0)) // rooting with negative base
{
k=floor((1.0/b)+0.5);
k/=2;
}
return cexp(cmul(cln(vec2(a,0.0),k),vec2(b,0.0))).x;
}
//-------------------------------------------------------------------------
I am using GLSL like math vec2
you can easily rewrite to x,y
components instead for example to this:
//-------------------------------------------------------------------------
float mypow(float a,float b) // a^b
{
if (b<0.0) return 1.0/mypow(a,-b);
int k=0;
if ((a<0.0)&&(b<1.0)) // rooting with negative base
{
k=floor((1.0/b)+0.5);
k/=2;
}
float x,y;
x=log(fabs(a));
y=atan2(0.0,a)+(float(k+k)*M_PI);
x*=b; y*=b;
// if (fabs(exp(x)*sin(y))>1e-6) throw domain error; // abs imaginary part is not zero
return exp(x)*cos(y); // real part of result
}
//-------------------------------------------------------------------------
Which returns real part of complex domain pow
and also select the correct multi-valued cln
sub-result. I also added domain test as a comment in the code in case you need/want to implement it.
Here result for your case:
mypow(-12.411202,0.200000) = -1.654866
Have tested more number and 1/odd number
exponents and looks like it is working.
[Edit1] handling mixed exponents
Now if we have exponents in form a^(b0+1/b1)
where b0,b1
are integers and a<0
we need to dissect the pow to 2 parts:
a^(b0+1/b1) = a^b0 * a^(1/b1)
so when added to above function:
//-------------------------------------------------------------------------
float mypow(float a,float b) // a^b
{
if (b<0.0) return 1.0/mypow(a,-b); // handle negative exponents
int k;
float x0,x,y,e,b0;
k=0; // for normal cases k=0
b0=floor(b); // integer part of exponent
b-=b0; // decimal part of exponent
// integer exponent (real domain power |a|^b0 )
x0=pow(fabs(a),b0);
if ((a<0.0)&&((int(b0)&1))==1) x0=-x0; // just add sign if odd exponent and negative base
// decimal exponent (complex domain rooting a^b )
if ((a<0.0)&&(b>0.0)) // rooting with negative base
{
k=floor((1.0/b)+0.5);
k&=0xFFFFFFFE;
}
x=b*(log(fabs(a))); e=exp(x);
y=b*(atan2(0.0,a)+(float(k)*M_PI));
x=e*cos(y);
// y=e*sin(y); if (fabs(y)>1e-6) throw domain error;
return x*x0; // full complex result is x0*(x+i*y)
}
//-------------------------------------------------------------------------
and sample output:
mypow(-12.41120243,3.200000) = 3163.76635742
mypow(3163.76635742,0.312500) = 12.41120243