complex_midi.c

00001 /******************************************************************************
00002 *******************************************************************************
00003 *                European Southern Observatory
00004 *              VLTI MIDI Data Reduction Software
00005 *
00006 * Module name:    complex.c
00007 * Description:    THIS MODULE CONTAINS ALL COMPLEX ARITHMETIC FUNCTIONS (except assembler ones)
00008 *
00009 * History:        
00010 * 03-Feb-03        (jmeisner) Created
00011 * 25-Apr-03        (csabet) Added title, directives and included in the MIDI pipeline
00012 *******************************************************************************
00013 ******************************************************************************/
00014 
00015 /******************************************************************************
00016 *    Compiler directives
00017 ******************************************************************************/
00018 
00019 /******************************************************************************
00020 *    Include files
00021 ******************************************************************************/
00022 #include <stdio.h>
00023 #include <cpl.h>
00024 #include <stdlib.h>
00025 #include <math.h>
00026 #include "complex_midi.h"
00027 
00028 
00029 /*============================ C O D E    A R E A ===========================*/
00030 struct Complex Czero={0.F, 0.F};    //    Available for all apps. DO NOT CHANGE IT!!!!
00031 
00032 struct Complex Addc(struct Complex z1, struct Complex z2)
00033 {
00034    struct Complex result;
00035    result.r = z1.r + z2.r;
00036    result.i = z1.i + z2.i;
00037    return result;
00038 }
00039 
00040 struct Complex Subtractc(struct Complex z1, struct Complex z2)
00041 {
00042    struct Complex result;
00043    result.r = z1.r - z2.r;
00044    result.i = z1.i - z2.i;
00045    return result;
00046 }
00047 
00048 struct Complex Multiplyc(struct Complex z1, struct Complex z2)
00049 {
00050    struct Complex result;
00051    result.r = z1.r*z2.r - z1.i*z2.i;
00052    result.i = z1.i*z2.r + z1.r*z2.i;
00053    return result;
00054 }
00055 
00056 struct Complex Dividec(struct Complex z1, struct Complex z2)
00057 {
00058    struct Complex temp;
00059 
00060    MultiplyConjPtr(&temp, &z1, &z2);
00061    return Scalec(temp, 1.F/Cmag2(z2));
00062 }
00063 
00064 
00065 // Definitions which act on pointers:
00066 
00067 void SubtractCptr(struct Complex * result, struct Complex *  z1, struct Complex *  z2)
00068 {
00069     result->r = z1->r - z2->r;
00070     result->i = z1->i - z2->i;
00071 }
00072 
00073 void AddCptr (struct Complex * result, struct Complex *  z1, struct Complex *  z2)
00074 {
00075     result->r = z1->r + z2->r;
00076     result->i = z1->i + z2->i;
00077 }
00078 
00079 void MultiplyCptr(struct Complex * result, struct Complex *  z1, struct Complex *  z2)
00080 {
00081     float temp;
00082     temp=z1->r;
00083     result->r = z1->r*z2->r - z1->i*z2->i;
00084 //    result.i = z1.i*z2.r + z1.r*z2.i;    //    Old way before pointers passed
00085     result->i = z1->i*z2->r + temp*z2->i ;
00086 }
00087 
00088 void MultiplyConjPtr(struct Complex * result, struct Complex *  z1, struct Complex *  z2)
00089 {
00090     float temp;
00091     temp=z1->r;
00092     result->r = z1->r*z2->r + z1->i*z2->i;
00093 //    result.i = z1.i*z2.r - z1.r*z2.i;
00094     result->i = z1->i*z2->r - temp*z2->i;
00095 }
00096 
00097 struct Complex Scalec(struct Complex z, float scale)
00098 {
00099    struct Complex result;
00100    result.r = scale * z.r;
00101    result.i = scale * z.i;
00102    return result;
00103 }
00104 
00105 struct Complex Unitc(struct Complex z)
00106 {
00107    double temp;
00108 RESTART:
00109    temp = z.r*z.r + z.i*z.i;
00110    if(temp < .0000000000000000000000000001)
00111    {
00112       z.r += .00000000000001;
00113       goto RESTART;
00114    }
00115    return Scalec(z, 1.F/sqrt(temp));
00116 }
00117 
00118 float Cmag(struct Complex z)
00119 {
00120    return (float) sqrt(z.r*z.r + z.i*z.i);
00121 }
00122 
00123 float Cmag2(struct Complex z)
00124 {
00125     return (z.r*z.r + z.i*z.i);
00126 }
00127 
00128 
00129 //    New Nov 9, 1999:
00130 //     Returns a positive real part, if 0 then returns neg imag part.
00131 struct Complex Csqrt(struct Complex value)
00132 {
00133     float mag;
00134     struct Complex result;
00135 
00136     // Special case:
00137     if(value.i==0.F)
00138     {
00139         if(value.r>0)
00140         {
00141             result.i = 0.F;
00142             result.r = (float) sqrt(value.r);
00143             return result;
00144         }
00145         //    Else:
00146         result.r = 0.F;
00147         result.i = -((float) sqrt(-value.r));
00148         return result;
00149     }
00150 
00151     mag = Cmag(value);
00152     result.r = (float) sqrt(.5*(mag+value.r));
00153     result.i = (float) sqrt(.5*(mag-value.r));
00154 
00155     if(value.i < 0.F)
00156         result.i = -result.i;
00157 
00158     return result;
00159 }
00160 
00161 //    Now defined in c:
00162 void GetScaledEtoJtimes(float Angle, struct Complex *Result, float scale)
00163 {
00164     Result->r = scale * (float) cos(Angle);
00165     Result->i = scale * (float) sin(Angle);
00166 }
00167 
00168 void GetEtoJtimes(float Angle, struct Complex *Result)
00169 {
00170     Result->r = (float) cos(Angle);
00171     Result->i = (float) sin(Angle);
00172 }
00173 
00174 void GetExpc(struct Complex *Result, struct Complex z)
00175 {
00176     
00177     GetScaledEtoJtimes(z.i, Result, (float) exp(z.r));
00178 }
00179 
00180 struct Complex jtimes(struct Complex z)
00181 {
00182    struct Complex result;
00183    result.i = z.r;
00184    result.r = -z.i;
00185    return result;
00186 }
00187 
00188 
00189 
00190 //    Richard added on these functions
00191 float Arg(struct Complex z)
00192 {
00193     if(fabs(z.r)<.000000000000000001)
00194         if(fabs(z.i)<.000000000000000001)
00195            return 0.F;
00196 //         NAH:   if (temp<0) temp = temp + 360.F;
00197     return (float) atan2(z.i,z.r);
00198 }
00199 
00200 void printC(struct Complex z)
00201 {
00202     if(fabs(z.i) < .00001F*fabs(z.r))
00203         z.i = 0.F;
00204 /***************************************
00205     {
00206         if(z.r < 0.F)
00207            cpl_msg_info(cpl_func,"%.4g + j 0 = %.4g @ 180ø\n", z.r, -z.r);
00208         else
00209            cpl_msg_info(cpl_func,"%.4g + j 0 = %.4g @ 0ø\n", z.r, z.r);
00210     }
00211     else
00212 ************************************************/    
00213    cpl_msg_info(cpl_func,"%.4g + j %.4g = %.4g @ %4.1fø\n",
00214                 z.r,z.i,Cmag(z), 57.2958F*Arg(z));
00215 //  cpl_msg_info(cpl_func,"real -  %.2f   imag -  %.2f  mag -  %.2f  phi -  %.2f\n",
00216 }
00217 
00218 /*****************************************************************************/

Generated on 11 Feb 2011 for MIDI Pipeline Reference Manual by  doxygen 1.6.1