complex_midi.c
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
00030 struct Complex Czero={0.F, 0.F};
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
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
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
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
00130
00131 struct Complex Csqrt(struct Complex value)
00132 {
00133 float mag;
00134 struct Complex result;
00135
00136
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
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
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
00191 float Arg(struct Complex z)
00192 {
00193 if(fabs(z.r)<.000000000000000001)
00194 if(fabs(z.i)<.000000000000000001)
00195 return 0.F;
00196
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
00207
00208
00209
00210
00211
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
00216 }
00217
00218