Add new or upgraded functions as of 01-09-22.
Add a function prototype for cmod. Rename function conj to conju because conj is already defined differently in complex.h
This commit is contained in:
parent
94a73ffef2
commit
954cc86e59
|
|
@ -1,11 +1,14 @@
|
|||
|
||||
#include "dense.h"
|
||||
#include "ngspice/ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include "ngspice/bool.h"
|
||||
#include "ngspice/iferrmsg.h"
|
||||
|
||||
inline double cmod(cplx a);
|
||||
|
||||
inline void setcplx(cplx* d, double r, double i)
|
||||
{
|
||||
d->re = r; d->im = i;
|
||||
|
|
@ -26,6 +29,18 @@ inline cplx cmultco(cplx a, cplx b)
|
|||
}
|
||||
|
||||
|
||||
|
||||
inline cplx cdivco(cplx a, cplx b)
|
||||
{
|
||||
cplx res;
|
||||
double dmod = cmod(b);
|
||||
dmod *= dmod;
|
||||
res.re = (a.re * b.re + a.im * b.im) / dmod;
|
||||
res.im = (a.im * b.re - a.re * b.im) / dmod;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
inline cplx cmultdo(cplx a, double d)
|
||||
{
|
||||
cplx res;
|
||||
|
|
@ -78,9 +93,14 @@ inline void csubd(cplx* res, cplx a, double d)
|
|||
res->re = a.re - d;
|
||||
}
|
||||
|
||||
inline double cmodinv(cplx a)
|
||||
{
|
||||
return 1.0 / cmod(a);
|
||||
}
|
||||
|
||||
inline double cmod(cplx a)
|
||||
{
|
||||
return 1.0 / (a.re * a.re + a.im * a.im);
|
||||
return (a.re * a.re + a.im * a.im);
|
||||
}
|
||||
|
||||
inline int ciszero(cplx a)
|
||||
|
|
@ -90,12 +110,21 @@ inline int ciszero(cplx a)
|
|||
inline cplx cinv(cplx a)
|
||||
{
|
||||
cplx res;
|
||||
double cpmod = cmod(a);
|
||||
double cpmod = cmodinv(a);
|
||||
res.re = a.re * cpmod;
|
||||
res.im = -a.im * cpmod;
|
||||
return res;
|
||||
}
|
||||
|
||||
inline cplx conju(cplx a)
|
||||
{
|
||||
cplx res;
|
||||
res.re = a.re;
|
||||
res.im = -a.im;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void showmat(Mat* A) {
|
||||
if (A->row > 0 && A->col > 0) {
|
||||
|
||||
|
|
@ -151,13 +180,18 @@ void showcmat(CMat* A) {
|
|||
}
|
||||
|
||||
CMat* newcmat(int r, int c, double dr, double di) {
|
||||
CMat* M = (CMat*)malloc(sizeof(CMat));
|
||||
CMat* M = (CMat*)tmalloc(sizeof(CMat));
|
||||
|
||||
if (M == NULL) return NULL;
|
||||
|
||||
M->row = r; M->col = c;
|
||||
M->d = (cplx**)malloc(sizeof(cplx*) * r);
|
||||
M->d = (cplx**)tmalloc(sizeof(cplx*) * r);
|
||||
if (M->d == NULL) {
|
||||
tfree(M); return NULL;
|
||||
}
|
||||
|
||||
for (int i = 0; i < r; i++)
|
||||
M->d[i] = (cplx*)malloc(sizeof(cplx) * c);
|
||||
M->d[i] = (cplx*)tmalloc(sizeof(cplx) * c);
|
||||
|
||||
for (int i = 0; i < M->row; i++) {
|
||||
for (int j = 0; j < M->col; j++) {
|
||||
|
|
@ -168,27 +202,47 @@ CMat* newcmat(int r, int c, double dr, double di) {
|
|||
return M;
|
||||
}
|
||||
|
||||
void init(Mat* A, double d)
|
||||
{
|
||||
for (int i = 0; i < A->row; i++) {
|
||||
for (int j = 0; j < A->col; j++) {
|
||||
A->d[i][j] = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
void cinit(CMat* A, double dr, double di)
|
||||
{
|
||||
cplx ci;
|
||||
ci.re = dr;
|
||||
ci.im = di;
|
||||
for (int i = 0; i < A->row; i++) {
|
||||
for (int j = 0; j < A->col; j++) {
|
||||
A->d[i][j] = ci;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
CMat* newcmatnoinit(int r, int c) {
|
||||
CMat* M = (CMat*)malloc(sizeof(CMat));
|
||||
CMat* M = (CMat*)tmalloc(sizeof(CMat));
|
||||
if (M == NULL) return NULL;
|
||||
M->row = r; M->col = c;
|
||||
|
||||
M->d = (cplx**)malloc(sizeof(cplx*) * r);
|
||||
M->d = (cplx**)tmalloc(sizeof(cplx*) * r);
|
||||
for (int i = 0; i < r; i++)
|
||||
M->d[i] = (cplx*)malloc(sizeof(cplx) * c);
|
||||
M->d[i] = (cplx*)tmalloc(sizeof(cplx) * c);
|
||||
return M;
|
||||
}
|
||||
|
||||
Mat* newmat(int r, int c, double d) {
|
||||
Mat* M = (Mat*)malloc(sizeof(Mat));
|
||||
Mat* M = (Mat*)tmalloc(sizeof(Mat));
|
||||
if (M == NULL) return NULL;
|
||||
|
||||
M->row = r; M->col = c;
|
||||
M->d = (double**)malloc(sizeof(double*) * r);
|
||||
M->d = (double**)tmalloc(sizeof(double*) * r);
|
||||
for (int i = 0; i < r; i++)
|
||||
M->d[i] = (double*)malloc(sizeof(double) * c);
|
||||
M->d[i] = (double*)tmalloc(sizeof(double) * c);
|
||||
|
||||
for (int i = 0; i < M->row; i++) {
|
||||
for (int j = 0; j < M->col; j++) {
|
||||
|
|
@ -199,13 +253,13 @@ Mat* newmat(int r, int c, double d) {
|
|||
}
|
||||
|
||||
Mat* newmatnoinit(int r, int c) {
|
||||
Mat* M = (Mat*)malloc(sizeof(Mat));
|
||||
Mat* M = (Mat*)tmalloc(sizeof(Mat));
|
||||
if (M == NULL) return NULL;
|
||||
|
||||
M->row = r; M->col = c;
|
||||
M->d = (double**)malloc(sizeof(double*) * r);
|
||||
M->d = (double**)tmalloc(sizeof(double*) * r);
|
||||
for (int i = 0; i < r; i++)
|
||||
M->d[i] = (double*)malloc(sizeof(double) * c);
|
||||
M->d[i] = (double*)tmalloc(sizeof(double) * c);
|
||||
|
||||
return M;
|
||||
}
|
||||
|
|
@ -217,16 +271,19 @@ void resizemat(Mat* A, int r, int c)
|
|||
if ((A->row == r) && (A->col == c))
|
||||
return;
|
||||
|
||||
for (int r = 0; r < A->row; r++)
|
||||
free(A->d[r]);
|
||||
for (int ri = 0; ri < A->row; ri++)
|
||||
tfree(A->d[ri]);
|
||||
|
||||
if (A->d != NULL)
|
||||
free(A->d);
|
||||
tfree(A->d);
|
||||
|
||||
A->row = r; A->col = c;
|
||||
A->d = (double**)malloc(sizeof(double*) * r);
|
||||
A->d = (double**)tmalloc(sizeof(double*) * r);
|
||||
|
||||
if (A->d == NULL) return;
|
||||
|
||||
for (int i = 0; i < r; i++)
|
||||
A->d[i] = (double*)malloc(sizeof(double) * c);
|
||||
A->d[i] = (double*)tmalloc(sizeof(double) * c);
|
||||
}
|
||||
|
||||
void resizecmat(CMat* A, int r, int c)
|
||||
|
|
@ -235,16 +292,19 @@ void resizecmat(CMat* A, int r, int c)
|
|||
if ((A->row == r) && (A->col == c))
|
||||
return;
|
||||
|
||||
for (int r = 0; r < A->row; r++)
|
||||
free(A->d[r]);
|
||||
for (int ri = 0; ri < A->row; ri++)
|
||||
tfree(A->d[ri]);
|
||||
|
||||
if (A->d != NULL)
|
||||
free(A->d);
|
||||
tfree(A->d);
|
||||
|
||||
A->row = r; A->col = c;
|
||||
A->d = (cplx**)malloc(sizeof(cplx*) * r);
|
||||
A->d = (cplx**)tmalloc(sizeof(cplx*) * r);
|
||||
|
||||
if (A->d == NULL) return;
|
||||
|
||||
for (int i = 0; i < r; i++)
|
||||
A->d[i] = (cplx*)malloc(sizeof(cplx) * c);
|
||||
A->d[i] = (cplx*)tmalloc(sizeof(cplx) * c);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -252,24 +312,24 @@ void freecmat(CMat* A) {
|
|||
if (A == NULL) return;
|
||||
|
||||
for (int r = 0; r < A->row; r++)
|
||||
free(A->d[r]);
|
||||
tfree(A->d[r]);
|
||||
|
||||
if (A->d!=NULL)
|
||||
free(A->d);
|
||||
tfree(A->d);
|
||||
|
||||
free(A);
|
||||
tfree(A);
|
||||
}
|
||||
|
||||
void freemat(Mat* A) {
|
||||
if (A == NULL) return;
|
||||
|
||||
for (int r = 0; r < A->row; r++)
|
||||
free(A->d[r]);
|
||||
tfree(A->d[r]);
|
||||
|
||||
if (A->d!=NULL)
|
||||
free(A->d);
|
||||
tfree(A->d);
|
||||
|
||||
free(A);
|
||||
tfree(A);
|
||||
}
|
||||
|
||||
CMat* ceye(int n) {
|
||||
|
|
@ -406,7 +466,7 @@ Mat* sum(Mat* A, Mat* B) {
|
|||
int r = A->row;
|
||||
int c = A->col;
|
||||
Mat* C = newmatnoinit(r, c);
|
||||
int k = 0;
|
||||
|
||||
for (int i = 0; i < r; i++) {
|
||||
for (int j = 0; j < c; j++) {
|
||||
C->d[i][j] = A->d[i][j] + B->d[i][j];
|
||||
|
|
@ -479,7 +539,7 @@ void submat2(Mat* A, Mat* B, int r1, int r2, int c1, int c2) {
|
|||
}
|
||||
|
||||
CMat* subcmat(CMat* A, int r1, int r2, int c1, int c2) {
|
||||
CMat* B = newmatnoinit(r2 - r1 + 1, c2 - c1 + 1);
|
||||
CMat* B = newcmatnoinit(r2 - r1 + 1, c2 - c1 + 1);
|
||||
int k = 0;
|
||||
for (int i = r1; i <= r2; i++) {
|
||||
for (int j = c1; j <= c2; j++) {
|
||||
|
|
@ -566,7 +626,7 @@ int cmultiplydest(CMat* A, CMat* B, CMat* dest) {
|
|||
return (OK);
|
||||
}
|
||||
else if (r2 == 1 && c2 == 1) {
|
||||
complexmultiply(A, B->d[0][0],dest);
|
||||
complexmultiplydest(A, B->d[0][0],dest);
|
||||
return (OK);
|
||||
}
|
||||
|
||||
|
|
@ -807,7 +867,14 @@ Mat* adjoint(Mat* A) {
|
|||
|
||||
|
||||
|
||||
|
||||
extern CMat* ctransposeconj(CMat* source)
|
||||
{
|
||||
CMat* dest = newcmatnoinit(source->col, source->row);
|
||||
for (int i = 0; i < dest->row; i++)
|
||||
for (int j = 0; j < dest->col; j++)
|
||||
dest->d[i][j] = conju(source->d[j][i]);
|
||||
return dest;
|
||||
}
|
||||
|
||||
CMat* cadjoint(CMat* A) {
|
||||
CMat* B = newcmatnoinit(A->row, A->col);
|
||||
|
|
@ -845,14 +912,16 @@ CMat* cinverse(CMat* A) {
|
|||
return C;
|
||||
}
|
||||
|
||||
int cinversedest(CMat* A, CMat* dest) {
|
||||
|
||||
void cinversedest(CMat* A, CMat* dest) {
|
||||
CMat* B = cadjoint(A);
|
||||
cplx de = cinv(cdet(A));
|
||||
|
||||
complexmultiplydest(B, de, dest);
|
||||
freecmat(B);
|
||||
return (OK);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Mat* copyvalue(Mat* A) {
|
||||
|
|
@ -938,7 +1007,7 @@ Mat* rowechelon(Mat* A) {
|
|||
int ind2 = 0;
|
||||
for (int i = 0; i < B->row; i++) {
|
||||
for (int j = 0; j < B->col; j++) {
|
||||
if (B->d[i * B->col + j] != 0 && j < ind1) {
|
||||
if (B->d[i][j] != 0 && j < ind1) {
|
||||
ind1 = j;
|
||||
ind2 = i;
|
||||
break;
|
||||
|
|
@ -1002,7 +1071,7 @@ Mat* rowechelon(Mat* A) {
|
|||
CMat* crowechelon(CMat* A) {
|
||||
if (A->row == 1) {
|
||||
for (int j = 0; j < A->col; j++) {
|
||||
if (cmod(A->d[0][j]) != 0) {
|
||||
if (cmodinv(A->d[0][j]) != 0) {
|
||||
CMat* B = complexmultiply(A,cinv(A->d[0][j]));
|
||||
return B;
|
||||
}
|
||||
|
|
@ -1093,7 +1162,7 @@ Mat* hconcat(Mat* A, Mat* B) {
|
|||
|
||||
CMat* chconcat(CMat* A, CMat* B) {
|
||||
CMat* C = newcmatnoinit(A->row, A->col + B->col);
|
||||
int k = 0;
|
||||
|
||||
for (int i = 0; i < A->row; i++) {
|
||||
int k = 0;
|
||||
for (int j = 0; j < A->col; j++, k++) {
|
||||
|
|
@ -1152,10 +1221,9 @@ double norm(Mat* A) {
|
|||
|
||||
double cnorm(CMat* A) {
|
||||
double d = 0;
|
||||
int k = 0;
|
||||
for (int i = 0; i < A->row; i++) {
|
||||
for (int j = 0; j < A->col; j++) {
|
||||
d += cmod(A->d[i][j]);
|
||||
d += cmodinv(A->d[i][j]);
|
||||
}
|
||||
}
|
||||
d = sqrt(d);
|
||||
|
|
@ -1218,9 +1286,9 @@ Mat* nullmat(Mat* A) {
|
|||
|
||||
MatList* lu(Mat* A) {
|
||||
if (A->row == 1) {
|
||||
MatList* ml = (MatList*)malloc(sizeof(MatList));
|
||||
MatList* ml = (MatList*)tmalloc(sizeof(MatList));
|
||||
ml->mat = newmat(1, 1, A->d[0][0]);
|
||||
ml->next = (MatList*)malloc(sizeof(MatList));
|
||||
ml->next = (MatList*)tmalloc(sizeof(MatList));
|
||||
ml->next->mat = newmat(1, 1, 1);
|
||||
return ml;
|
||||
}
|
||||
|
|
@ -1260,13 +1328,13 @@ MatList* lu(Mat* A) {
|
|||
}
|
||||
}
|
||||
}
|
||||
MatList* ml = (MatList*)malloc(sizeof(MatList));
|
||||
MatList* ml = (MatList*)tmalloc(sizeof(MatList));
|
||||
ml->mat = L;
|
||||
ml->next = (MatList*)malloc(sizeof(MatList));;
|
||||
ml->next = (MatList*)tmalloc(sizeof(MatList));;
|
||||
ml->next->mat = U;
|
||||
freemat(w);
|
||||
freemat(v);
|
||||
free(mlb);
|
||||
tfree(mlb);
|
||||
return ml;
|
||||
}
|
||||
|
||||
|
|
@ -1313,9 +1381,9 @@ MatList* qr(Mat* A) {
|
|||
R->d[j][j1] = innermultiply(uj, submat(A, 0, r-1, j1, j1)) / nuj;
|
||||
}
|
||||
}
|
||||
MatList* ml = (MatList*)malloc(sizeof(MatList));
|
||||
MatList* ml = (MatList*)tmalloc(sizeof(MatList));
|
||||
ml->mat = Q;
|
||||
ml->next = (MatList*)malloc(sizeof(MatList));;
|
||||
ml->next = (MatList*)tmalloc(sizeof(MatList));;
|
||||
ml->next->mat = R;
|
||||
freemat(ek);
|
||||
freemat(uj);
|
||||
|
|
|
|||
Loading…
Reference in New Issue