// This program illustrates using user-defined functions to perform // complex math and trig functions, logarithms, etc. // Since user-defined functions can only return one value, // separate functions return the real and imaginary parts // of each function. // Refer to a textbook on Complex Variables. long "all" // not required, unless long precision is desired. 100 input "Enter real, imaginary: "; in_real, in_imag // Keep in mind the range of each function when entering values. // (small numbers work best) // calculate exponential exp_real = fnexpz_real (in_real, in_imag) exp_imag = fnexpz_imag (in_real, in_imag) print "exp(z) [real]: "; exp_real print " [imag]: "; exp_imag // calculate log log_real = fnlogz_real (exp_real, exp_imag) log_imag = fnlogz_imag (exp_real, exp_imag) print "log(z) [real]: "; log_real print " [imag]: "; log_imag // calculate sin sin_real = fnsinz_real (in_real, in_imag) sin_imag = fnsinz_imag (in_real, in_imag) print "sin(z) [real]: "; sin_real print " [imag]: "; sin_imag // calculate cosine cos_real = fncosz_real (in_real, in_imag) cos_imag = fncosz_imag (in_real, in_imag) print "cos(z) [real]: "; cos_real print " [imag]: "; cos_imag // Calculate sin^2 + cos^2 (should equal 1) sx2 = fnmultz_real (sin_real, sin_imag, sin_real, sin_imag) sy2 = fnmultz_imag (sin_real, sin_imag, sin_real, sin_imag) cx2 = fnmultz_real (cos_real, cos_imag, cos_real, cos_imag) cy2 = fnmultz_imag (cos_real, cos_imag, cos_real, cos_imag) real = sx2 + cx2 imag = sy2 + cy2 print "s2+c2 [real]: "; real print " [imag]: "; imag // Calculate tangent tan_real = fntanz_real (in_real, in_imag) tan_imag = fntanz_imag (in_real, in_imag) print "tan [real]: "; tan_real print " [imag]: "; tan_imag // Calculate arctangent - should yield original values // if range is not exceeded. atn_real = fnatnz_real (tan_real, tan_imag) atn_imag = fnatnz_imag (tan_real, tan_imag) print "atn [real]: "; atn_real print " [imag]: "; atn_imag // Calculate cube using log and exp if (in_real = 0) then goto 300 // win't work for pure imaginary log3_real = fnlogz_real (in_real, in_imag) log3_imag = fnlogz_imag (in_real, in_imag) log3_3_real = fnmultz_real (log3_real, log3_imag, 3, 0) log3_3_imag = fnmultz_imag (log3_real, log3_imag, 3, 0) cube_real = fnexpz_real (log3_3_real, log3_3_imag) cube_imag = fnexpz_imag (log3_3_real, log3_3_imag) print "cube [real]: "; cube_real print " [imag]: "; cube_imag // Now calculate the cube root - should return original number log3_real = fnlogz_real (cube_real, cube_imag) log3_imag = fnlogz_imag (cube_real, cube_imag) log3_3_real = fndivz_real (log3_real, log3_imag, 3, 0) log3_3_imag = fndivz_imag (log3_real, log3_imag, 3, 0) cuberoot_real = fnexpz_real (log3_3_real, log3_3_imag) cuberoot_imag = fnexpz_imag (log3_3_real, log3_3_imag) print "cube- [real]: "; cuberoot_real print "root [imag]: "; cuberoot_imag 300 // Now calculate the exp (i * pi) -- should equal -1 eipi_real = fnexpz_real (0, pi) eipi_imag = fnexpz_imag (0, pi) print "e^ipi [real]: "; eipi_real print " [imag]: "; eipi_imag // Calculate the square root sqrt_real = fnsqrz_real (in_real, in_imag) sqrt_imag = fnsqrz_imag (in_real, in_imag) print "sqrt [real]: "; sqrt_real print " [imag]: "; sqrt_imag goto 100 // USER-DEFINED FUNCTIONS FOR COMPLEX OPERATIONS: //-------------------------------------- // Complex Exponential -- exp (x + iy) def fnexpz_real(x, y) = exp(x) * cos (y) def fnexpz_imag(x, y) = exp(x) * sin (y) //----------------------------------------- // Complex natural log -- ln (x + iy) // works for primary complex plane (-pi < theta < pi) def fnlogz_real (x,y) = log (sqr(x*x + y*y)) def fnlogz_imag (x,y) = gosub 1250 1250 // complex log // works for primary complex plane (-pi < theta < pi) // if x = 0, we have a problem if (x < 0 and y >= 0) then return atn(y/x) + pi if (x < 0 and y < 0) then return atn(y/x) - pi return atn (y/x) //--------------------------------------------- // Hyperbolic sine and cosine (needed for complex sine and cosine) def fnsinh (y) = (exp(y) - exp(-y))/2 def fncosh (y) = (exp(y) + exp(-y))/2 //--------------------------------------------- // Complex sine -- sin (x + iy) def fnsinz_real (x, y) = sin (x) * fncosh (y) def fnsinz_imag (x, y) = cos (x) * fnsinh (y) //--------------------------------------------- // Complex cosine -- cos (x + iy) def fncosz_real (x, y) = cos (x) * fncosh (y) def fncosz_imag (x, y) = -sin (x) * fnsinh (y) //--------------------------------------------- // complex multiply -- (x1 + iy1) * (x2 + iy2) def fnmultz_real (x1, y1, x2, y2)= x1 * x2 - y1 * y2 def fnmultz_imag (x1, y1, x2, y2)= x1 * y2 + x2 * y1 //--------------------------------------------- // complex divide -- (x1 + iy1) / (x2 + iy2) def fndivz_real (x1, y1, x2, y2) = (x1 * x2 + y1 * y2) / (x2 * x2 + y2 * y2) def fndivz_imag (x1, y1, x2, y2) = (y1 * x2 - x1 * y2) / (x2 * x2 + y2 * y2) //---------------------------------------- // Complex tangent -- tan (x + iy) def fntanz_real (x, y) = fndivz_real (fnsinz_real(x,y), fnsinz_imag(x,y), fncosz_real (x,y), fncosz_imag (x,y)) def fntanz_imag (x, y) = fndivz_imag (fnsinz_real(x,y), fnsinz_imag(x,y), fncosz_real (x,y), fncosz_imag (x,y)) //---------------------------------------- // Complex arctangent -- atn (x + iy) // atn (z) = 1/2 i (ln(1-iz) - ln(1+iz)) // = 1/2 i (ln (1 - i (x + iy)) - ln (1 + i (x + iy)) // = 1/2 i (ln (1 + y, -ix) - ln (1 - y + ix)) def fnatnz_real (x, y) = 0.5 * (fnlogz_imag (1-y, x) - fnlogz_imag (1+y, -x)) def fnatnz_imag (x, y) = 0.5 * (fnlogz_real (1+y, -x) - fnlogz_real (1-y, x)) //----------------------------------------------- // Complex square root -- sqr (x + iy) def fnsqrz_real(x,y) = sqr ((x + sqr (x*x + y*y))/ 2) def fnsqrz_imag(x,y) = (sgn(y)+(y = 0)) * sqr((sqr(x*x + y*y) - x)/2) // Note: (sgn(y) + (y = 0)) gives sgn(y) or 1 if y=0 //-----------------------------------------------