📄 matrix.c
字号:
/* Copy M2 to the top of M1 */
for ( i = 0; i < ptm2->row; i++ )
{
for ( j = 0; j < ptm1->col; j++ )
{
ptm1->mat[i][j] = ptm2->mat[i][j];
}
}
/* Copy M3 to the bottom of M1 */
for ( i = 0; i < ptm3->row; i++ )
{
for ( j = 0; j < ptm1->col; j++ )
{
ptm1->mat[i+(ptm2->row)][j] = ptm3->mat[i][j];
}
}
}
/*
* CONCAT :
* --------
* Concatenates parts of two vectors (either rows or columns). The
* part of each vector is specified by the beginning and ending index
* of the part, which is to concatenated with the other.
*
* Inputs : ptv0 - Pointer to resulting vector.
* ptv1 - Pointer to first argument vector.
* ptv2 - Pointer to second argument vector.
* beg1 - Beginning index of first vector.
* end1 - Ending index of first vector.
* beg2 - Beginning index of second vector.
* end2 - Ending index of second vector.
*/
void concat(matrix* ptv0,matrix* ptv1,matrix* ptv2,int beg1,int end1,int beg2,int end2)
{
register int i, n1, n2;
n1 = end1 - beg1 + 1; /* Number of elements in first vector. */
n2 = end2 - beg2 + 1; /* Number of elements in second vector. */
#if RUNCHK
/* Check that all arguments are vectors. */
if (!(((ptv0->row==1)||(ptv0->col==1))&&((ptv1->row==1)||(ptv1->col==1))&&((ptv2->row==1)||(ptv2->col==1)))) \
merror("Input is not a vector error in concat!");
/* Check whether indices are inside bounds. */
if ((end1 > (ptv1->row + ptv1->col - 2))||(end2 > (ptv2->row + ptv2->col - 2))) \
merror("Index is outside vector bounds error in concat!");
/* Check the dimension matching. */
if ((n1 + n2) != (ptv0->row + ptv0->col - 1)) \
merror("Dimension mismatch error in concat!");
#endif
/* Copy part of first vector to beginning of result vector. */
for ( i = 0; i < n1; i++ ) {
vput( ptv0, i, vget( ptv1, i+beg1 ) );
}
/* Copy part of second vector to end of result vector. */
for ( i = 0; i < n2; i++ ) {
vput( ptv0, i+n1, vget( ptv2, i+beg2 ) );
}
}
/*
* MAT2MAT
* _______
*
* Inserts a matrix (Matrix 2) into another matrix (Matrix 1).
*
* [ ]
* M1 = [ [M2]]
* [ ]
*
* Inputs: *ptm1 - Pointer Matrix 1
* row,col - Coordinates to the element where the
* upper left corner of matrix 2 is placed
* *ptm2 - Pointer to Matrix 2
*
*/
void mat2mat( matrix *ptm1, int row, int col, matrix *ptm2 )
{
register int i2,j2;
int i1, j1, rows2, cols2;
rows2 = ptm2->row; /* Number of rows in Matrix 2 */
cols2 = ptm2->col; /* Number of columns in Matrix 2 */
#if RUNCHK
/* Check whether the insertion is possible. */
if( row+rows2 > ptm1->row || col+cols2 > ptm1->col )
merror("Dimension mismatch in function MAT2MAT");
#endif
/* Insert Matrix 2 into Matrix 1 */
for( i1=row,i2=0; i2<rows2; i1++,i2++ )
{
for( j1=col,j2=0; j2<cols2; j1++,j2++ )
{
ptm1->mat[i1][j1] = ptm2->mat[i2][j2];
}
}
}
/*
* SHIFT :
* -------
* Shifts all elements of a vector and inserts a new value
* in the first element. The last element is lost. The
* function works on both column vectors and row vectors.
*
* Inputs: *ptm : Pointer to the vector to be shifted
* new_element : New element to be inserted
*/
void shift( matrix *ptm, double new_element)
{
register int i,j;
if (ptm->col == 1) /* Column vector */
{
for(i=ptm->row-2,j=i+1; j>0; i--,j--) /* Shift elements down */
ptm->mat[j][0] = ptm->mat[i][0];
ptm->mat[0][0] = new_element; /* Insert new element */
}
else if (ptm->row == 1) /* Row vector */
{
for(i=ptm->col-2,j=i+1; j>0; i--,j--) /* Shift elements right */
{
ptm->mat[0][j] = ptm->mat[0][i];
}
ptm->mat[0][0] = new_element; /* Insert new element */
}
else merror("Dimension mismatch error in funcion shift!"); /* Not a vector */
}
/*
* SUBMAT
* ------
* This function picks a submatrix from a larger matrix.
*
* Inputs: *ptm1 - Pointer to the result matrix
* *ptm2 - Pointer to input matrix
* rowbeg - Number of the first row
* rowend - Number of the last row
* colbeg - Number of the first column
* colend - Number of the last column
*/
void submat( matrix *ptm1, matrix *ptm2, int rowbeg, int rowend, int colbeg, int colend )
{
register int i1,i2,j1,j2;
#if RUNCHK
if ( rowend > ptm2->row-1 || colend > ptm2->col-1 ) \
merror("Argument out of range in function submat!");
if (((rowend-rowbeg)!=(ptm1->row-1))||((colend-colbeg)!=(ptm1->col-1)))\
merror("Dimension mismatch error in function submat!");
#endif
for ( i1=0,i2=rowbeg; i2<=rowend; i1++,i2++ )
{
for ( j1=0,j2=colbeg; j2<=colend; j1++,j2++ ) \
ptm1->mat[i1][j1] = ptm2->mat[i2][j2];
}
}
/*
* SUBVEC
* ------
*
* Inputs: *ptm1 - Pointer to the result vector
* *ptm2 - Pointer to input vector
* elem1 - Number of the first element
* elem2 - Number of the last element
*/
void subvec( matrix *ptm1, matrix *ptm2, int elem1, int elem2 )
{
register int i,j;
#if RUNCHK
/* Check whether elem2 is inside bound */
if ( elem2 > ptm2->row + ptm2->col - 2 ) \
merror("Argument out of range in function subvec!");
/* Check whether sub-vector fits output-vector. */
if ((ptm1->row + ptm1->col) != ( elem2 - elem1 + 2 )) \
merror("Wrong number of elements error in subvec!");
#endif
if ( ptm2->col == 1 ) /* Column vector */
{
for ( i=0,j=elem1; j<=elem2; i++,j++ ) \
ptm1->mat[i][0] = ptm2->mat[j][0];
}
else if ( ptm2->row == 1 ) /* Row vector */
{
for ( i=0,j=elem1; j<=elem2; i++,j++ ) \
ptm1->mat[0][i] = ptm2->mat[0][j];
}
else merror("Dimension mismatch in function subvec"); /* Not a vector */
}
/*
* GETROWS
* -------
*
* This function gets the number of rows in a matrix
*
* Input: *ptm - Pointer to matrix
*
* Output: rows - Number of rows in matrix
*
*/
int getrows(matrix *ptm)
{
return ptm->row;
}
/*
* GETCOLS
* -------
*
* This function gets the number of columns in a matrix
*
* Input: *ptm - Pointer to matrix
*
* Output: columns - Number of columns in matrix
*
*/
int getcols(matrix *ptm)
{
return ptm->col;
}
/*
* LENGTH :
* --------
* Determines the length of a row- or column- vector.
* Input : ptv - Pointer to the vector.
* Output : length - Length of the vector. (The number of elements.)
*/
int length( matrix* ptv )
{
register int length;
#if RUNCHK
if ( !( (ptv->row==1) || (ptv->col==1) ) ) \
merror("Input argument is not a vector error in length!");
#endif
length = ptv->row + ptv->col - 1;
return length;
}
/*
* MSCMP
* -----
*
* This function compares a string and a row vector containing a
* MATLAB string loaded by mload.
* If the to strings are identical 1 is returned. Otherwise the
* function returns 0.
*
* Input: mat - Pointer to "string vector"
* string - String expression
*
*/
int mscmp( matrix *mat, char *string )
{
int i, matlength;
matlength=length(mat);
for( i=0 ; (char)get_val(mat,0,i) == *(string+i) && i<matlength ; i++ );
if( (i==matlength) && *(string+i)=='\0') return 1;
else return 0;
}
#ifndef NO_IO /* For compilation by the DSP ANSI-C compiler. */
/*
* loadmat - C language routine to load a matrix from a MAT-file.
*
* Here is an example that uses 'loadmat' to load a matrix from a MAT-file:
*
* FILE *fp;
* char name[20];
* int type, mrows, ncols, imagf;
* double *xr, *xi;
* fp = fopen("foo.mat","rb");
* loadmat(fp, &type, name, &mrows, &ncols, &imagf, &xr, &xi);
* fclose(fp);
* free(xr);
* if (imagf) free(xi);
*
* The 'loadmat' routine returns 0 if the read is successful and 1 if
* and end-of-file or read error is encountered. 'loadmat' can be called
* repeatedly until the file is exhausted and an EOF is encountered.
*
* Author J.N. Little 11-3-86
*
* Modified by Steffen Torp, Servolaboratoriet 14-10-92.
*/
int loadmat(FILE *fp,int *type,char *pname,int *mrows,int *ncols,int *imagf,double **preal,double **pimag)
/* FILE *fp; File pointer */
/* int *type; Type flag: see reference section of guide */
/* int *mrows; row dimension */
/* int *ncols; column dimension */
/* int *imagf; imaginary flag */
/* char *pname; pointer to matrix name */
/* double **preal; pointer to real data */
/* double **pimag; pointer to imag data */
{
Fmatrix x;
int mn, namlen, conv;
/*
* Get Fmatrix structure from file
*/
if (fread((char *)&x, sizeof(Fmatrix), 1, fp) != 1) {
return(1);
}
/* Check if the mat-file is created on a platform similar to */
/* the actual platform. If yes, the flag 'conv' will be FALSE*/
/* Otherwise it will be TRUE */
if (SYSTEM == 0) {
switch (x.type) {
case 0L: conv = FALSE; break;
case 1L: conv = FALSE; break;
case 0xE8030000L: conv = TRUE; break;
case 0xE9030000L: conv = TRUE; break;
default: {
printf("\nUnknown file type in loadmat!\n");
printf("The type is: %lx \n",x.type);
exit(1);
}
}
}
else if (SYSTEM == 1000) {
switch (x.type) {
case 0L: conv = TRUE; break;
case 0x1000000L: conv = TRUE; break;
case 1000L: conv = FALSE; break;
case 1001L: conv = FALSE; break;
default: {
printf("\nUnknown file type in loadmat!\n");
printf("The type is: %lx \n",x.type);
exit(1);
}
}
}
if(conv==TRUE)
{
*type = (int)longconv(x.type);
*mrows = (int)longconv(x.mrows);
*ncols = (int)longconv(x.ncols);
*imagf = (int)longconv(x.imagf);
namlen = (int)longconv(x.namlen);
mn = (*mrows)*(*ncols);
}
else
{
*type = (int)(x.type);
*mrows = (int)(x.mrows);
*ncols = (int)(x.ncols);
*imagf = (int)(x.imagf);
namlen = (int)(x.namlen);
mn = (*mrows)*(*ncols);
}
/*
* Get matrix name from file
*/
if (fread(pname, sizeof(char), namlen, fp) != namlen) {
return(1);
}
/*
* Get Real part of matrix from file
*/
if (mn) {
*preal = (double *)malloc(mn*sizeof(double));
if (!(*preal)) {
printf("\nError: Variable too big to load\n");
return(1);
}
if (fread(*preal, sizeof(double), mn, fp) != mn) {
free(*preal);
return(1);
}
if(conv==TRUE) matconv(mn,*preal);
}
/*
* Get Imag part of matrix from file, if it exists
*/
if (x.imagf) {
*pimag = (double *)malloc(mn*sizeof(double));
if (!(*pimag)) {
printf("\nError: Variable too big to load\n");
free(*preal);
return(1);
}
if (fread(*pimag, sizeof(double), mn, fp) != mn) {
free(*pimag);
free(*preal);
return(1);
}
if(conv==TRUE) matconv(mn,*pimag);
}
return(0);
}
/*
* savemat - C language routine to save a matrix in a MAT-file.
*
* Here is an example that uses 'savemat' to save two matrices to disk,
* the second of which is complex:
*
* FILE *fp;
* double xyz[1000], ar[1000], ai[1000];
* fp = fopen("foo.mat","wb");
* savemat(fp, 2000, "xyz", 2, 3, 0, xyz, (double *)0);
* savemat(fp, 2000, "a", 5, 5, 1, ar, ai);
* fclose(fp);
*
* Author J.N. Little 11-3-86
*/
void savemat(FILE *fp,int type,char *pname,int mrows,int ncols,int imagf,double *preal,double *pimag)
/* FILE *fp; File pointer */
/* int type; Type flag: Normally 0 for PC, 1000 for Sun, Mac, and */
/* Apollo, 2000 for VAX D-float, 3000 for VAX G-float */
/* Add 1 for text variables. */
/* See LOAD in reference section of guide for more info. */
/* int mrows; row dimension */
/* int ncols; column dimension */
/* int imagf; imaginary flag */
/* char *pname; pointer to matrix name */
/* double *preal; pointer to real data */
/* double *pimag; pointer to imag data */
{
Fmatrix x;
int mn;
x.type = (long)type;
x.mrows = (long)mrows;
x.ncols = (long)ncols;
x.imagf = (long)imagf;
x.namlen = (long)strlen(pname) + 1L;
mn = (int)(x.mrows * x.ncols);
fwrite(&x, sizeof(Fmatrix), 1, fp);
fwrite(pname, sizeof(char), (int)x.namlen, fp);
fwrite(preal, sizeof(double), mn, fp);
if (imagf) {
fwrite(pimag, sizeof(double), mn, fp);
}
}
/*
* LONGCONV
* --------
*
* This function flips long integers, in order to convert longs
* from INTEL to MOTOROLA format or vice versa.
*
* INPUT : inval - Long integer to be converted
*
* OUTPUT : outval - The converted long.
*
*/
long longconv(long inval)
{
char *ptc1, *ptc2;
int i, j;
long outval;
ptc1=(char*)(&inval);
ptc2=(char*)(&outval);
for(i=0,j=3;i<4;i++,j--)
{
*(ptc2+i)=*(ptc1+j);
}
return(outval);
}
/*
* MATCONV
* -------
*
* This function flips a number of doubles, in a consecutive part
* of the memory, in order to convert matrix data from INTEL to
* MOTOROLA format or vice versa.
*
* INPUT : mn - Number of elements in the matrix
* ptd - Pointer to the first element
*
*
*/
void matconv(int mn, double *ptd)
{
char *ptc;
char tmp;
int i, j, k;
for(k=0;k<mn;k++)
{
/* Flip the k'th double */
ptc=(char*)(ptd+k);
for(i=0,j=7;i<4;i++,j--)
{
tmp=*(ptc+i);
*(ptc+i)=*(ptc+j);
*(ptc+j)=tmp;
}
}
}
#endif /* I/O functions are not available in the DSP compiler. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -