Skip to content

Instantly share code, notes, and snippets.

@dasbluehole
Created December 2, 2020 07:34
Show Gist options
  • Save dasbluehole/893edc521b657c6904b4fa72f51f65c5 to your computer and use it in GitHub Desktop.
Save dasbluehole/893edc521b657c6904b4fa72f51f65c5 to your computer and use it in GitHub Desktop.
Simple Complex number and operators implementations. It also calculates nth roots of any number. See the main() function.
/*
* simplex.c
*
* Copyright(C) 2020 Ashok Shankar Das <ashok.s.das@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*
*/
/* !Info:
* Simplex is a set of routines for handling complex numbers
* these routines may not be very optimal but definitely workable.
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
// datatype defination to store the complex number
// x+jy has real part x and imaginary part +y
// so x is stored in .real and +y is stored in .imag field
// of the structure
typedef struct Complex
{
double real,
imag;
}Complex;
// datatype to store the polar form of complex number
// r*cis(theta)
// r is magnitude sqrt(x^2+y^2)
// theta is angle of the radius vector to x-axis in
// CCw direction expressed in radians
typedef struct polar
{
double radius,
theta;
}Cpolar;
/* !f gets real part of a complex number
* !i Complex
* !o double
*/
double get_real(Complex c)
{
return(c.real);
}
/* !f gets imaginary part of a complex number
* !i Complex
* !o double
*/
double get_imag(Complex c)
{
return(c.imag);
}
/* !f sets real part of a complex number
* !i pointer to Complex , double
* !o nothing
*/
void set_real(Complex *c, double r)
{
c->real = r;
}
/* !f sets imaginary part of a complex number
* !i pointer to Complex , double
* !o nothing
*/
void set_imag(Complex *c, double img)
{
c->imag = img;
}
/* !f makes a complex number
* !f accepts real part and imaginary part as double
* !i r double , i double
* !o Complex
*/
Complex mk_complex(double r, double im)
{
Complex z;
set_real(&z,r);
set_imag(&z,im);
return(z);
}
/* !f prints a complex number
* !i Complex
* !o nothing
*/
void print_complex(Complex c)
{
char sgn = '+';
double r,im;
r=get_real(c);
im=get_imag(c);
if(im<0.0)
{
sgn = '-';
im = -1*im;
}
printf("%lf%cj%lf\n",r,sgn,im);
}
/* !f converts a complex number to string in x+jy form
* !i Complex, pre allocated char buffer
* !o nothing
*/
void complex_to_str(Complex c,char *str)
{
char sgn = '+';
double r,im;
r=get_real(c);
im=get_imag(c);
if(im<0.0)
{
sgn = '-';
im = -1*im;
}
sprintf(str,"%lf%cj%lf",r,sgn,im);
}
/* !f converts a string in "x+jy" form to Complex
* !i string in "x+iy" format
* !o Complex
*/
Complex string_to_complex(char *s)
{
Complex zc;
char r_str[15]="0";
char i_str[15]="0";
char sgn='\0';
if(strchr(s,'j'))
{
int index=strchr(s,'j')-s;
strncpy(r_str,s,index-1);
strcpy(i_str,s+index+1);
sgn = *(s+index-1);
}
set_real(&zc,atof(r_str));
if(sgn=='-')
{
set_imag(&zc,-1*atof(i_str));
}
else
set_imag(&zc,atof(i_str));
return(zc);
}
// arith ops
/* !f adds 2 complex numbers
* !i Complex, Complex
* !o Complex
*/
Complex Cadd(Complex c1, Complex c2)
{
Complex z;
set_real(&z,get_real(c1)+get_real(c2));
set_imag(&z,get_imag(c1)+get_imag(c2));
return(z);
}
/* !f subtracts 2 complex numbers
* !i Complex, Complex
* !o Complex
*/
Complex Csub(Complex c1, Complex c2)
{
Complex z;
set_real(&z,get_real(c1)-get_real(c2));
set_imag(&z,get_imag(c1)-get_imag(c2));
return(z);
}
/* !f conjugate of a complex numbers
* !i Complex
* !o Complex
*/
Complex Cconjugate(Complex c)
{
Complex z;
set_real(&z,get_real(c));
set_imag(&z,-1*get_imag(c));
return(z);
}
/* !f multiplies 2 complex numbers
* !i Complex, Complex
* !o Complex
*/
Complex Cmul(Complex c1, Complex c2)
{
Complex z;
double rp1,ip1,rp2,ip2;
double r,i;
rp1=get_real(c1);
ip1=get_imag(c1);
rp2=get_real(c2);
ip2=get_imag(c2);
r = rp1*rp2-ip1*ip2;
i = rp1*ip2+rp2*ip1;
set_real(&z,r);
set_imag(&z,i);
return (z);
}
/* !f reciprocal of a complex numbers
* !i Complex
* !o Complex
*/
Complex Creciprocal(Complex c)
{
Complex z,cj;
double r,i,t;
r = get_real(c);
i = get_imag(c);
t = r*r+i*i;
cj = Cconjugate(c);
set_real(&z,get_real(cj)/t);
set_imag(&z,get_imag(cj)/t);
return(z);
}
/* !f devides a Complex with second Complex
* !i Complex, Complex
* !o Complex
*/
Complex Cdiv(Complex c1, Complex c2)
{
Complex z;
z = Creciprocal(c2);
z = Cmul(c1,z);
return(z);
}
/* !f magnitude of a complex numbers
* !i Complex
* !o double
*/
double Cmod(Complex c)
{
double m;
double r,i;
r = get_real(c);
i = get_imag(c);
m = sqrt(r*r+i*i);
return(m);
}
/* !f square root of a complex numbers
* !i Complex
* !o Complex
*/
Complex Csqrt(Complex c)
{
double r,i,sgn=1;
r = get_real(c);
i = get_imag(c);
Complex z;
if(i == 0)
{
z = mk_complex(sqrt(r),0);
return(z);
}
double m;
m=sqrt(r*r+i*i);
if(i<0)
sgn=-1;
z = mk_complex(sqrt((m+r)/2),sgn*(sqrt((m-r)/2)));
return (z);
}
// polar co-ordinate helper function
/* !f gets radius vector from polar structure
* !i Cpolar
* !o double
*/
double get_radiusv(Cpolar p)
{
return (p.radius);
}
/* !f sets radius vector from polar structure
* !i pointer to Cpolar, double
* !o nothing
*/
void set_radiusv(Cpolar *p,double rad)
{
p->radius = rad;
}
/* !f gets angle of radius vector from polar structure
* !i Cpolar
* !o double (radian)
*/
double get_theta(Cpolar p)
{
return (p.theta);
}
/* !f sets angle of radius vector
* !i pointer to Cpolar, double
* !o nothing
*/
void set_theta(Cpolar *p, double theta)
{
p->theta = theta;
}
/* !f Complex form to polar form
* !i Complex
* !o Cpolar
*/
Cpolar complex_to_polar(Complex c)
{
Cpolar p;
double x,y;
x = get_real(c);
y = get_imag(c);
double mag = sqrt(x*x+y*y);
double ang = atan2(y,x);
set_radiusv(&p, mag);
set_theta(&p, ang);
return(p);
}
/* !f polar form to Complex form
* !i Complex
* !o Cpolar
*/
Complex polar_to_complex(Cpolar p)
{
Complex z;
double x,y;
double mag,th;
mag = get_radiusv(p);
th = get_theta(p);
x = mag * cos(th);
y = mag * sin(th);
set_real(&z,x);
set_imag(&z,y);
return(z);
}
/* !f Raises a Complex to a integral power
* !i Complex, Integer
* !o Complex
*/
Complex Cnpow(Complex c, int n)
{
// x+iy can be written as r(cos(theta)+i*Sin(theta)) => r*e^(i*(theta))
// hence (x+iy)^n = (r*e^(i*(theta)))^n
// =(r^n)*e^(i*n*theta) = (r^n)*(cos(n*theta)+i*sin(n*theta))
// now we can convert it back to cartesian format
Cpolar p;
double rn,nt;
p = complex_to_polar(c);
rn = pow(get_radiusv(p),n);
nt = get_theta(p)*n;
double x, y;
x = rn * cos(nt);
y = rn * sin(nt);
Complex z = mk_complex(x,y);
return(z);
}
/* !f finds n number of nth roots of a Complex number
* !i Complex, Integer, pre allocated array of Complex
* !o nothing
*/
void Cnroot(Complex c, int n, Complex *root)
{
Cpolar p = complex_to_polar(c);
double m = get_radiusv(p);
double th = get_theta(p);
for(int i=0; i< n; i++)
{
double x = pow(m,1.0/n)*(cos((th+2*M_PI*i)/n));
double y = pow(m,1.0/n)*(sin((th+2*M_PI*i)/n));
root[i] = mk_complex(x,y);
}
}
int main()
{
Complex z;
set_real(&z,2);
set_imag(&z,3);
char st[30];
print_complex(z);
complex_to_str(z,st);
printf("%s\n",st);
strcpy(st,"15.0-j20.0");
printf("%s\n",st);
Complex z1 = string_to_complex(st);
print_complex(z1);
complex_to_str(z1,st);
printf("%s\n",st);
set_real(&z1,-20.3);
set_imag(&z1,-33.543);
print_complex(z1);
complex_to_str(z1,st);
printf("%s\n",st);
Complex z2=mk_complex(3,5);
Complex z3=mk_complex(4,-3);
print_complex(z2);
print_complex(z3);
Complex z4 = Cadd(z2,z3);
print_complex(z4);
Complex z5=mk_complex(3,2);
Complex z6=mk_complex(1,7);
Complex z7=Cmul(z5,z6);
print_complex(z7);
Complex z8 = mk_complex(1,1);
z8 = Cmul(z8,z8);
print_complex(z8);
Complex z9 = mk_complex(2,3);
Complex z10= mk_complex(4,-5);
Complex z11 = Cdiv(z9,z10);
print_complex(z11);
z10 = Creciprocal(z10);
z11 = Cmul(z9,z10);
print_complex(z11);
Complex z12 = mk_complex(8,-6);
Complex z13 = Csqrt(z12);
print_complex(z13);
Complex z14 = Cnpow(z13,2);
print_complex(z14);
Complex z15[30];
z14 = mk_complex(1,0);
Cnroot(z14,4,z15);
print_complex(z15[0]);
print_complex(z15[1]);
print_complex(z15[2]);
print_complex(z15[3]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment