|
Isis 3.0 Object Programmers' Reference |
Home |
00001 00023 #include <cmath> 00024 00025 #include "ProcessByLine.h" 00026 #include "Calculator.h" 00027 #include "InfixToPostfix.h" 00028 #include "iException.h" 00029 #include "SpecialPixel.h" 00030 00031 using namespace std; 00032 00033 namespace Isis { 00049 double NegateOperator(double a) { return -1*a; } 00050 00051 00060 double MultiplyOperator(double a, double b) { return a*b; } 00061 00062 00071 double DivideOperator(double a, double b) { return a/b; } 00072 00073 00082 double AddOperator(double a, double b) { return a+b; } 00083 00084 00093 double SubtractOperator(double a, double b) { return a-b; } 00094 00095 00104 double GreaterThanOperator(double a, double b) { return a > b ? 1.0 : 0.0; } 00105 00106 00115 double LessThanOperator(double a, double b) { return a < b ? 1.0 : 0.0; } 00116 00117 00126 double EqualOperator(double a, double b) { return a == b ? 1.0 : 0.0; } 00127 00128 00137 double GreaterThanOrEqualOperator(double a, double b) { return a >= b ? 1.0 : 0.0; } 00138 00139 00148 double LessThanOrEqualOperator(double a, double b) { return a <= b ? 1.0 : 0.0; } 00149 00150 00159 double NotEqualOperator(double a, double b) { return a != b ? 1.0 : 0.0; } 00160 00161 00169 double CosecantOperator(double a) { return 1.0 / sin(a); } 00170 00171 00179 double SecantOperator(double a) { return 1.0 / cos(a); } 00180 00188 double CotangentOperator(double a) { return 1.0 / tan(a); } 00189 00190 00198 int Round(double a) { return (a>0)? (int)(a+0.5) : (int)(a-0.5); } 00199 00200 00209 double BitwiseAndOperator(double a, double b) { return (double)(Round(a)&Round(b)); } 00210 00211 00220 double BitwiseOrOperator(double a, double b) { return (double)(Round(a)|Round(b)); } 00221 00222 00231 double ModulusOperator(double a, double b) { return (double)(Round(a)%Round(b)); } 00232 00233 00235 Calculator::Calculator() {} 00236 00237 00241 void Calculator::Negative() { 00242 std::vector<double> result = Pop(); 00243 PerformOperation(result, result.begin(), result.end(), NegateOperator); 00244 Push(result); 00245 } 00246 00247 00251 void Calculator::Multiply() { 00252 std::vector<double> y = Pop(); 00253 std::vector<double> x = Pop(); 00254 std::vector<double> result; 00255 00256 PerformOperation(result, x.begin(), x.end(), y.begin(), y.end(), MultiplyOperator); 00257 Push(result); 00258 } 00259 00260 00264 void Calculator::Add() { 00265 std::vector<double> y = Pop(); 00266 std::vector<double> x = Pop(); 00267 std::vector<double> result; 00268 PerformOperation(result, x.begin(), x.end(), y.begin(), y.end(), AddOperator); 00269 Push(result); 00270 } 00271 00272 00276 void Calculator::Subtract() { 00277 std::vector<double> y = Pop(); 00278 std::vector<double> x = Pop(); 00279 std::vector<double> result; 00280 PerformOperation(result, x.begin(), x.end(), y.begin(), y.end(), SubtractOperator); 00281 Push(result); 00282 } 00283 00284 00288 void Calculator::Divide() { 00289 std::vector<double> y = Pop(); 00290 std::vector<double> x = Pop(); 00291 std::vector<double> result; 00292 00293 PerformOperation(result, x.begin(), x.end(), y.begin(), y.end(), DivideOperator); 00294 Push(result); 00295 } 00296 00300 void Calculator::Modulus() { 00301 std::vector<double> y = Pop(); 00302 std::vector<double> x = Pop(); 00303 std::vector<double> result; 00304 00305 PerformOperation(result, x.begin(), x.end(), y.begin(), y.end(), ModulusOperator); 00306 Push(result); 00307 } 00308 00309 00316 void Calculator::Exponent() { 00317 std::vector<double> exponent = Pop(); 00318 std::vector<double> x = Pop(); 00319 std::vector<double> result; 00320 00321 PerformOperation(result, x.begin(), x.end(), exponent.begin(), exponent.end(), pow); 00322 Push(result); 00323 } 00324 00325 00331 void Calculator::SquareRoot() { 00332 std::vector<double> result = Pop(); 00333 PerformOperation(result, result.begin(), result.end(), sqrt); 00334 Push(result); 00335 } 00336 00337 00341 void Calculator::AbsoluteValue() { 00342 std::vector<double> result = Pop(); 00343 PerformOperation(result, result.begin(), result.end(), fabs); 00344 Push(result); 00345 } 00346 00347 00353 void Calculator::Log() { 00354 std::vector<double> result = Pop(); 00355 PerformOperation(result, result.begin(), result.end(), log); 00356 Push(result); 00357 } 00358 00359 00363 void Calculator::Log10() { 00364 std::vector<double> result = Pop(); 00365 PerformOperation(result, result.begin(), result.end(), log10); 00366 Push(result); 00367 } 00368 00369 00375 void Calculator::LeftShift() { 00376 std::vector<double> y = Pop(); 00377 if(y.size() != 1) { 00378 std::string msg = "Must use scalars for shifting."; 00379 throw Isis::iException::Message(Isis::iException::Math, msg, _FILEINFO_); 00380 } 00381 else { 00382 std::vector<double> x = Pop(); 00383 00384 if((int)y[0] > (int)x.size()) { 00385 std::string msg = "Shift value must be <= to number of samples."; 00386 throw Isis::iException::Message(Isis::iException::Math, msg, _FILEINFO_); 00387 } 00388 else { 00389 std::vector<double> result; 00390 int shift = (int)y[0]; 00391 result.resize(x.size()); 00392 00393 for(unsigned int i = 0; i < result.size(); i++) { 00394 if(i+shift < x.size() && i+shift >= 0) 00395 result[i] = x[i+shift]; 00396 else 00397 result[i] = sqrt(-1.0); // create a NaN 00398 } 00399 00400 Push(result); 00401 } 00402 } 00403 } 00404 00405 00411 void Calculator::RightShift() { 00412 std::vector<double> y = Pop(); 00413 if(y.size() != 1) { 00414 std::string msg = "Must use scalars for shifting."; 00415 throw Isis::iException::Message(Isis::iException::Math, msg, _FILEINFO_); 00416 } 00417 else { 00418 std::vector<double> x = Pop(); 00419 00420 if((int)y[0] > (int)x.size()) { 00421 std::string msg = "Shift value must be <= to number of samples."; 00422 throw Isis::iException::Message(Isis::iException::Math, msg, _FILEINFO_); 00423 } 00424 else { 00425 std::vector<double> result; 00426 int shift = (int)y[0]; 00427 result.resize(x.size()); 00428 00429 for(int i = 0; i < (int)result.size(); i++) { 00430 if(i-shift < (int)x.size() && i-shift >= 0) { 00431 result[i] = x[i-shift]; 00432 } 00433 else { 00434 result[i] = sqrt(-1.0); // create a NaN 00435 } 00436 } 00437 00438 Push(result); 00439 } 00440 } 00441 } 00442 00443 00447 void Calculator::Minimum() { 00448 std::vector<double> result = Pop(); 00449 00450 int size = result.size(); 00451 double minVal = result[0]; 00452 for(unsigned int i = 0; i < result.size(); i++) minVal = min(minVal, result[i]); 00453 00454 result.clear(); 00455 result.resize(size, minVal); 00456 Push(result); 00457 } 00458 00459 00463 void Calculator::Maximum() { 00464 std::vector<double> result = Pop(); 00465 00466 int size = result.size(); 00467 double maxVal = result[0]; 00468 for(unsigned int i = 0; i < result.size(); i++) maxVal = max(maxVal, result[i]); 00469 00470 result.clear(); 00471 result.resize(size, maxVal); 00472 Push(result); 00473 } 00474 00475 00480 void Calculator::GreaterThan() { 00481 std::vector<double> y = Pop(); 00482 std::vector<double> x = Pop(); 00483 std::vector<double> result; 00484 00485 PerformOperation(result, x.begin(), x.end(), y.begin(), y.end(), GreaterThanOperator); 00486 Push(result); 00487 } 00488 00489 00494 void Calculator::LessThan() { 00495 std::vector<double> y = Pop(); 00496 std::vector<double> x = Pop(); 00497 std::vector<double> result; 00498 00499 PerformOperation(result, x.begin(), x.end(), y.begin(), y.end(), LessThanOperator); 00500 Push(result); 00501 } 00502 00503 00508 void Calculator::Equal() { 00509 std::vector<double> y = Pop(); 00510 std::vector<double> x = Pop(); 00511 std::vector<double> result; 00512 00513 PerformOperation(result, x.begin(), x.end(), y.begin(), y.end(), EqualOperator); 00514 Push(result); 00515 } 00516 00517 00522 void Calculator::GreaterThanOrEqual() { 00523 std::vector<double> y = Pop(); 00524 std::vector<double> x = Pop(); 00525 std::vector<double> result; 00526 00527 PerformOperation(result, x.begin(), x.end(), y.begin(), y.end(), GreaterThanOrEqualOperator); 00528 Push(result); 00529 } 00530 00531 00536 void Calculator::LessThanOrEqual() { 00537 std::vector<double> y = Pop(); 00538 std::vector<double> x = Pop(); 00539 std::vector<double> result; 00540 00541 PerformOperation(result, x.begin(), x.end(), y.begin(), y.end(), LessThanOrEqualOperator); 00542 Push(result); 00543 } 00544 00545 00550 void Calculator::NotEqual() { 00551 std::vector<double> y = Pop(); 00552 std::vector<double> x = Pop(); 00553 std::vector<double> result; 00554 00555 PerformOperation(result, x.begin(), x.end(), y.begin(), y.end(), NotEqualOperator); 00556 Push(result); 00557 } 00558 00559 00560 // Commented out because bitwise ops only work with integers instead of doubles 00561 00565 void Calculator::And() { 00566 std::vector<double> y = Pop(); 00567 std::vector<double> x = Pop(); 00568 std::vector<double> result; 00569 00570 PerformOperation(result, x.begin(), x.end(), y.begin(), y.end(), BitwiseAndOperator); 00571 Push(result); 00572 } 00573 00574 00578 void Calculator::Or() { 00579 std::vector<double> y = Pop(); 00580 std::vector<double> x = Pop(); 00581 std::vector<double> result; 00582 00583 PerformOperation(result, x.begin(), x.end(), y.begin(), y.end(), BitwiseOrOperator); 00584 Push(result); 00585 } 00586 00587 00591 void Calculator::Sine() { 00592 std::vector<double> result = Pop(); 00593 PerformOperation(result, result.begin(), result.end(), sin); 00594 Push(result); 00595 } 00596 00597 00601 void Calculator::Cosine() { 00602 std::vector<double> result = Pop(); 00603 PerformOperation(result, result.begin(), result.end(), cos); 00604 Push(result); 00605 } 00606 00607 00611 void Calculator::Tangent() { 00612 std::vector<double> result = Pop(); 00613 PerformOperation(result, result.begin(), result.end(), tan); 00614 Push(result); 00615 } 00616 00617 00621 void Calculator::Cosecant() { 00622 std::vector<double> result = Pop(); 00623 PerformOperation(result, result.begin(), result.end(), CosecantOperator); 00624 Push(result); 00625 } 00626 00627 00631 void Calculator::Secant() { 00632 std::vector<double> result = Pop(); 00633 PerformOperation(result, result.begin(), result.end(), SecantOperator); 00634 Push(result); 00635 } 00636 00637 00641 void Calculator::Cotangent() { 00642 std::vector<double> result = Pop(); 00643 PerformOperation(result, result.begin(), result.end(), CotangentOperator); 00644 Push(result); 00645 } 00646 00647 00651 void Calculator::Arcsine() { 00652 std::vector<double> result = Pop(); 00653 PerformOperation(result, result.begin(), result.end(), asin); 00654 Push(result); 00655 } 00656 00657 00661 void Calculator::Arccosine() { 00662 std::vector<double> result = Pop(); 00663 PerformOperation(result, result.begin(), result.end(), acos); 00664 Push(result); 00665 } 00666 00667 00671 void Calculator::Arctangent() { 00672 std::vector<double> result = Pop(); 00673 PerformOperation(result, result.begin(), result.end(), atan); 00674 Push(result); 00675 } 00676 00677 00681 void Calculator::ArcsineH() { 00682 std::vector<double> result = Pop(); 00683 PerformOperation(result, result.begin(), result.end(), asinh); 00684 Push(result); 00685 } 00686 00687 00691 void Calculator::ArccosineH() { 00692 std::vector<double> result = Pop(); 00693 PerformOperation(result, result.begin(), result.end(), acosh); 00694 Push(result); 00695 } 00696 00697 00701 void Calculator::ArctangentH() { 00702 std::vector<double> result = Pop(); 00703 PerformOperation(result, result.begin(), result.end(), atanh); 00704 Push(result); 00705 } 00706 00707 00711 void Calculator::Arctangent2() { 00712 std::vector<double> y = Pop(); 00713 std::vector<double> x = Pop(); 00714 std::vector<double> result; 00715 00716 PerformOperation(result, x.begin(), x.end(), y.begin(), y.end(), atan2); 00717 p_valStack.push(result); 00718 } 00719 00720 00724 void Calculator::SineH() { 00725 std::vector<double> result = Pop(); 00726 PerformOperation(result, result.begin(), result.end(), sinh); 00727 Push(result); 00728 } 00729 00730 00734 void Calculator::CosineH() { 00735 std::vector<double> result = Pop(); 00736 PerformOperation(result, result.begin(), result.end(), cosh); 00737 Push(result); 00738 } 00739 00740 00744 void Calculator::TangentH() { 00745 std::vector<double> result = Pop(); 00746 PerformOperation(result, result.begin(), result.end(), tanh); 00747 Push(result); 00748 } 00749 00750 00751 // Stack methods 00752 00758 void Calculator::Push(std::vector<double> &vect) { 00759 p_valStack.push(vect); 00760 } 00761 00762 00768 void Calculator::Push(double scalar) { 00769 std::vector<double> s; 00770 s.push_back(scalar); 00771 Push(s); 00772 } 00773 00774 00780 void Calculator::Push(Buffer &buff) { 00781 std::vector<double> b(buff.size()); 00782 00783 for(int i = 0; i < buff.size(); i++) { 00784 // Test for special pixels and map them to valid values 00785 if(IsSpecial(buff[i])) { 00786 if(Isis::IsNullPixel(buff[i])) { 00787 //b[i] = NAN; 00788 b[i] = sqrt(-1.0); 00789 } 00790 else if(Isis::IsHrsPixel(buff[i])) { 00791 //b[i] = INFINITY; 00792 b[i] = DBL_MAX * 2; 00793 } 00794 else if(Isis::IsHisPixel(buff[i])) { 00795 //b[i] = INFINITY; 00796 b[i] = DBL_MAX * 2; 00797 } 00798 else if(Isis::IsLrsPixel(buff[i])) { 00799 //b[i] = -INFINITY; 00800 b[i] = -DBL_MAX * 2; 00801 } 00802 else if(Isis::IsLisPixel(buff[i])) { 00803 //b[i] = -INFINITY; 00804 b[i] = -DBL_MAX * 2; 00805 } 00806 } 00807 else 00808 b[i] = buff[i]; 00809 } 00810 p_valStack.push(b); 00811 } 00812 00813 00823 std::vector<double> Calculator::Pop(bool keepSpecials) { 00824 std::vector<double> top; 00825 00826 if(p_valStack.empty()) { 00827 std::string msg = "Stack is empty, cannot perform any more operations."; 00828 throw Isis::iException::Message(Isis::iException::Math, msg, _FILEINFO_); 00829 } 00830 00831 top = p_valStack.top(); 00832 00833 if(keepSpecials) { 00834 for(int i = 0; i < (int)top.size(); i++) { 00835 if(isnan(top[i])) { 00836 top[i] = Isis::Null; 00837 } 00838 // Test for +INFINITY 00839 else if(top[i] > DBL_MAX) { 00840 top[i] = Isis::Hrs; 00841 } 00842 // Test for -INFINITY) 00843 else if(top[i] < -DBL_MAX) { 00844 top[i] = Isis::Lrs; 00845 } 00846 else { 00847 // Do nothing 00848 } 00849 } 00850 } 00851 00852 p_valStack.pop(); 00853 00854 00855 return top; 00856 } 00857 00858 00862 void Calculator::PrintTop() { 00863 if(p_valStack.empty()) return; 00864 00865 std::cout << "[ "; 00866 std::vector<double> top = p_valStack.top(); 00867 for(int i = 0; i < (int)top.size(); i++) { 00868 std::cout << top[i] << " "; 00869 } 00870 std::cout << "]" << std::endl; 00871 } 00872 00873 00879 bool Calculator::Empty() { 00880 return p_valStack.empty(); 00881 } 00882 00883 00887 void Calculator::Clear() { 00888 while(!p_valStack.empty()) { 00889 p_valStack.pop(); 00890 } 00891 } 00892 00893 00903 void Calculator::PerformOperation(std::vector<double> &results, 00904 std::vector<double>::iterator arg1Start, 00905 std::vector<double>::iterator arg1End, 00906 double operation(double)) 00907 { 00908 results.resize(arg1End-arg1Start); 00909 00910 for(unsigned int pos = 0; pos < results.size(); pos++) { 00911 results[pos] = operation(*arg1Start); 00912 arg1Start++; 00913 } 00914 } 00915 00916 00932 void Calculator::PerformOperation(std::vector<double> &results, 00933 std::vector<double>::iterator arg1Start, 00934 std::vector<double>::iterator arg1End, 00935 std::vector<double>::iterator arg2Start, 00936 std::vector<double>::iterator arg2End, 00937 double operation(double, double)) { 00938 if(arg1End-arg1Start != 1 && arg2End-arg2Start != 1 && 00939 arg1End-arg1Start != arg2End-arg2Start) { 00940 std::string msg = "Cannot operate on vectors of differing sizes."; 00941 throw Isis::iException::Message(Isis::iException::Math, msg, _FILEINFO_); 00942 } 00943 00944 int iSize = max(arg1End-arg1Start, arg2End-arg2Start); 00945 results.resize(iSize); 00946 00947 for(unsigned int pos = 0; pos < results.size(); pos++) { 00948 results[pos] = operation(*arg1Start, *arg2Start); 00949 00950 if(arg1Start+1 != arg1End) arg1Start++; 00951 if(arg2Start+1 != arg2End) arg2Start++; 00952 } 00953 } 00954 } // End of namespace Isis