#include #include #include #include #include "output.h" #include "funcs.h" #include "matrix.h" #include "linear.h" #include "interval.h" #include "mainloop.h" #define wrong_arg() { error=26; output("Wrong argument\n"); return; } void minmax (double *x, long n, double *min, double *max, int *imin, int *imax) /***** minmax compute the total minimum and maximum of n double numbers. *****/ { long i; if (n==0) { *min=0; *max=0; *imin=0; *imax=0; return; } *min=*x; *max=*x; *imin=0; *imax=0; x++; for (i=1; i*max) { *max=*x; *imax=(int)i; } x++; } } /**************************************************************************** * utility functions * ****************************************************************************/ void msize (header *hd) { header *result,*st=hd,*hd1,*end=(header *)newram; int r,c,r0=0,c0=0; if (!hd) wrong_arg_in("size"); result=new_matrix(1,2,""); if (error) return; while (end>hd) { hd1=getvariable(hd); if (!hd1) varnotfound("size"); if (hd1->type==s_matrix || hd1->type==s_cmatrix || hd1->type==s_imatrix) { r=dimsof(hd1)->r; c=dimsof(hd1)->c; } else if (hd1->type==s_real || hd1->type==s_complex || hd1->type==s_interval) { r=c=1; } else if (hd1->type==s_submatrix || hd1->type==s_csubmatrix || hd1->type==s_isubmatrix) { r=submdimsof(hd1)->r; c=submdimsof(hd1)->c; } else wrong_arg_in("size"); if ((r>1 && r0>1 && r!=r0) || (c>1 && c0>1 && c!=c0)) { if (r0!=r && c0!=c) { output("Matrix dimensions must agree for size!\n"); error=1021; return; } } else { if (r>r0) r0=r; if (c>c0) c0=c; } hd=nextof(hd); } *matrixof(result)=r0; *(matrixof(result)+1)=c0; moveresult(st,result); } void mcols (header *hd) { header *st=hd,*res; int n; hd=getvalue(hd); if (error) return; switch (hd->type) { case s_matrix : case s_cmatrix : case s_imatrix : n=dimsof(hd)->c; break; case s_submatrix : case s_csubmatrix : case s_isubmatrix : n=submdimsof(hd)->c; break; case s_real : case s_complex : case s_interval : n=1; break; case s_string : n=(int)strlen(stringof(hd)); break; default : wrong_arg_in("cols"); } res=new_real(n,""); if (error) return; moveresult(st,res); } void mrows (header *hd) { header *st=hd,*res; int n; hd=getvalue(hd); if (error) return; switch (hd->type) { case s_matrix : case s_cmatrix : case s_imatrix : n=dimsof(hd)->r; break; case s_submatrix : case s_csubmatrix : case s_isubmatrix : n=submdimsof(hd)->r; break; case s_real : case s_complex : case s_interval : n=1; break; default : wrong_arg_in("rows"); } res=new_real(n,""); if (error) return; moveresult(st,res); } void mredim (header *hd) { header *st=hd,*hd1,*result; int c1,r1; double *m; unsigned long i,n,size1,size; hd1=nextof(hd); hd=getvalue(hd); if (error) return; hd1=getvalue(hd1); if (error) return; if (hd1->type!=s_matrix || dimsof(hd1)->r!=1 || dimsof(hd1)->c!=2 || (hd->type!=s_matrix && hd->type!=s_cmatrix)) wrong_arg_in("redim"); m=matrixof(hd1); if (*m<1 || *m>INT_MAX) wrong_arg_in("redim"); r1=(int)(*m++); if (*m<1 || *m>INT_MAX) wrong_arg_in("redim"); c1=(int)(*m); size1=(long)c1*r1; size=(long)dimsof(hd)->c*dimsof(hd)->r; if (sizetype==s_matrix) { result=new_matrix(r1,c1,""); if (error) return; memmove((char *)matrixof(result),(char *)matrixof(hd), n*sizeof(double)); if (ntype==s_cmatrix) { result=new_cmatrix(r1,c1,""); if (error) return; memmove((char *)matrixof(result),(char *)matrixof(hd), 2*n*sizeof(double)); if (ntype!=s_matrix || dimsof(hd1)->r!=1 || dimsof(hd1)->c!=2) wrong_arg_in("redim"); m=matrixof(hd1); if (*m<1 || *m>INT_MAX) wrong_arg_in("redim"); r1=(int)(*m++); if (*m<1 || *m>INT_MAX) wrong_arg_in("redim"); c1=(int)(*m); getmatrix(hd,&r0,&c0,&m0); mm=m0; if ((r0!=1 && r1!=r0) || (c0!=1 && c1!=c0)) { output("Cannot resize these!\n"); error=1; return; } if (hd->type==s_matrix || hd->type==s_real) { result=new_matrix(r1,c1,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_cmatrix || hd->type==s_complex) { result=new_cmatrix(r1,c1,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_imatrix || hd->type==s_interval) { result=new_imatrix(r1,c1,""); if (error) return; mr=matrixof(result); for (i=0; itype!=s_real || step->type!=s_real || end->type!=s_real) { output("The : allows only real arguments!\n"); error=15; return; } vinit=*realof(init); vstep=*realof(step); vend=*realof(end); if (vstep==0) { output("A step size of 0 is not allowed in : \n"); error=401; return; } if (fabs(vend-vinit)/fabs(vstep)+1+epsilon>INT_MAX) { output1("A vector can only have %d elements\n",INT_MAX); error=402; return; } count=(int)(floor(fabs(vend-vinit)/fabs(vstep)+1+epsilon)); if ((vend>vinit && vstep<0) || (vend0)) count=0; result=new_matrix(1,count,""); if (error) return; m=matrixof(result); while (count>=0) { *m++=vinit; vinit+=vstep; count--; } moveresult(st,result); } void mmatrix (header *hd) { header *st=hd,*hd1,*result; long i,n; double x,xi; double *m,*mr; int c,r,c1,r1; hd1=nextof(hd); hd=getvalue(hd); if (error) return; hd1=getvalue(hd1); if (error) return; if (hd->type==s_matrix) { getmatrix(hd,&r,&c,&m); if (*m<0 || *m>INT_MAX || *(m+1)<0 || *(m+1)>INT_MAX) wrong_arg_in("matrix"); r1=(int)*m; c1=(int)*(m+1); if (hd1->type==s_real) { result=new_matrix(r1,c1,""); mr=matrixof(result); x=*realof(hd1); n=(long)c1*r1; for (i=0; itype==s_complex) { result=new_cmatrix(r1,c1,""); mr=matrixof(result); x=*realof(hd1); xi=*(realof(hd1)+1); n=(long)c1*r1; for (i=0; itype!=s_matrix || dimsof(hd)->r!=1 || dimsof(hd)->c!=2) wrong_arg_in("zeros"); rows=*matrixof(hd); cols=*(matrixof(hd)+1); if (rows<0 || rows>=INT_MAX || cols<0 || cols>=INT_MAX) wrong_arg_in("zeros"); r=(int)rows; c=(int)cols; result=new_matrix(r,c,""); if (error) return; m=matrixof(result); n=c*r; for (i=0; itype!=s_matrix || dimsof(hd)->r!=1 || dimsof(hd)->c!=2) wrong_arg_in("ones"); rows=*matrixof(hd); cols=*(matrixof(hd)+1); if (rows<0 || rows>=INT_MAX || cols<0 || cols>=INT_MAX) wrong_arg_in("ones"); r=(int)rows; c=(int)cols; result=new_matrix(r,c,""); if (error) return; m=matrixof(result); n=c*r; for (i=0; itype!=s_matrix || dimsof(hd)->r!=1 || dimsof(hd)->c!=2) wrong_arg_in("diag"); rows=*matrixof(hd); cols=*(matrixof(hd)+1); if (rows<0 || rows>=INT_MAX || cols<0 || cols>=INT_MAX) wrong_arg_in("diag"); r=(int)rows; c=(int)cols; hd1=next_param(st); if (hd1) hd2=next_param(hd1); if (hd1) hd1=getvalue(hd1); if (hd2) hd2=getvalue(hd2); if (error) return; if (hd1->type!=s_real) wrong_arg_in("diag"); k=(int)*realof(hd1); if (hd2->type==s_matrix || hd2->type==s_real) { result=new_matrix(r,c,""); if (error) return; m=matrixof(result); n=(long)c*r; for (l=0; l=0 && i+ktype==s_cmatrix || hd2->type==s_complex) { result=new_cmatrix(r,c,""); if (error) return; m=matrixof(result); n=(long)2*(long)c*r; for (l=0; l=0 && i+ktype==s_imatrix || hd2->type==s_interval) { result=new_imatrix(r,c,""); if (error) return; m=matrixof(result); n=(long)2*(long)c*r; for (l=0; l=0 && i+ktype!=s_matrix && hd->type!=s_cmatrix) wrong_arg_in("setdiag"); getmatrix(hd,&c,&r,&mhd); hd1=next_param(st); if (hd1) hd2=next_param(hd1); if (hd1) hd1=getvalue(hd1); if (hd2) hd2=getvalue(hd2); if (error) return; if (hd1->type!=s_real) wrong_arg_in("setdiag"); k=(int)*realof(hd1); if (hd->type==s_matrix && (hd2->type==s_complex || hd2->type==s_cmatrix)) { make_complex(st); msetdiag(st); return; } else if (hd->type==s_cmatrix && (hd2->type==s_real || hd2->type==s_matrix)) { make_complex(nextof(nextof(st))); msetdiag(st); return; } else if (hd->type==s_imatrix && (hd2->type==s_real || hd2->type==s_matrix)) { make_interval(nextof(nextof(st))); msetdiag(st); return; } if (hd->type==s_matrix) { result=new_matrix(r,c,""); if (error) return; m=matrixof(result); memmove((char *)m,(char *)mhd,(long)c*r*sizeof(double)); getmatrix(hd2,&rd,&cd,&md); if (rd!=1 || cd<1) wrong_arg_in("setdiag"); for (i=0; i=0 && i+ktype==s_cmatrix) { result=new_cmatrix(r,c,""); if (error) return; m=matrixof(result); memmove((char *)m,(char *)mhd,(long)c*r*(long)2*sizeof(double)); getmatrix(hd2,&rd,&cd,&md); if (rd!=1 || cd<1) wrong_arg_in("setdiag"); m=matrixof(result); for (i=0; i=0 && i+ktype!=s_real) wrong_arg(); n=(int)*realof(hd1); if (hd->type==s_matrix || hd->type==s_real) { getmatrix(hd,&r,&c,&m); result=new_matrix(1,r,""); if (error) return; mr=matrixof(result); l=0; for (i=0; i=c) break; if (i+n>=0) { l++; *mr++=*mat(m,c,i,i+n); } } dimsof(result)->c=l; result->size=matrixsize(1,c); } else if (hd->type==s_cmatrix || hd->type==s_complex) { getmatrix(hd,&r,&c,&m); result=new_cmatrix(1,r,""); if (error) return; mr=matrixof(result); l=0; for (i=0; i=c) break; if (i+n>=0) { l++; mh=cmat(m,c,i,i+n); *mr++=*mh++; *mr++=*mh; } } dimsof(result)->c=l; result->size=cmatrixsize(1,c); } else wrong_arg(); moveresult(st,result); } void mband (header *hd) { header *st=hd,*hd1,*hd2,*result; int i,j,c,r,n1,n2; double *m,*mr; hd1=next_param(hd); hd2=next_param(hd1); hd=getvalue(hd); hd1=getvalue(hd1); hd2=getvalue(hd2); if (error) return; if (hd1->type!=s_real || hd2->type!=s_real) wrong_arg(); n1=(int)*realof(hd1); n2=(int)*realof(hd2); if (hd->type==s_matrix || hd->type==s_real) { getmatrix(hd,&r,&c,&m); result=new_matrix(r,c,""); if (error) return; mr=matrixof(result); for (i=0; i=n1 && j-i<=n2) *mr++=*m++; else { *mr++=0.0; m++; } } } else if (hd->type==s_cmatrix || hd->type==s_complex) { getmatrix(hd,&r,&c,&m); result=new_cmatrix(r,c,""); if (error) return; mr=matrixof(result); for (i=0; i=n1 && j-i<=n2) { *mr++=*m++; *mr++=*m++; } else { *mr++=0.0; *mr++=0.0; m+=2; } } } else wrong_arg(); moveresult(st,result); } void mdup (header *hd) { header *result,*st=hd,*hd1; double x,*m,*m1,*m2; int c,i,n,j,r; hd=getvalue(hd); hd1=next_param(st); if (!hd1) wrong_arg(); hd1=getvalue(hd1); if (error) return; if (hd1->type!=s_real) wrong_arg(); x=*realof(hd1); n=(int)x; if (n<1 || x>=INT_MAX) wrong_arg(); if (hd->type==s_matrix && dimsof(hd)->r==1) { c=dimsof(hd)->c; result=new_matrix(n,c,""); if (error) return; m1=matrixof(hd); m2=matrixof(result); for (i=0; itype==s_matrix && dimsof(hd)->c==1) { r=dimsof(hd)->r; result=new_matrix(r,n,""); if (error) return; m1=matrixof(hd); m2=matrixof(result); for (i=0; itype==s_real) { result=new_matrix(n,1,""); if (error) return; m1=matrixof(result); for (i=0; itype==s_cmatrix && dimsof(hd)->r==1) { c=dimsof(hd)->c; result=new_cmatrix(n,c,""); if (error) return; m1=matrixof(hd); m2=matrixof(result); for (i=0; itype==s_cmatrix && dimsof(hd)->c==1) { r=dimsof(hd)->r; result=new_cmatrix(r,n,""); if (error) return; m1=matrixof(hd); m2=matrixof(result); for (i=0; itype==s_complex) { result=new_cmatrix(n,1,""); if (error) return; m1=matrixof(result); for (i=0; itype==s_imatrix && dimsof(hd)->r==1) { c=dimsof(hd)->c; result=new_imatrix(n,c,""); if (error) return; m1=matrixof(hd); m2=matrixof(result); for (i=0; itype==s_imatrix && dimsof(hd)->c==1) { r=dimsof(hd)->r; result=new_imatrix(r,n,""); if (error) return; m1=matrixof(hd); m2=matrixof(result); for (i=0; itype==s_interval) { result=new_imatrix(n,1,""); if (error) return; m1=matrixof(result); for (i=0; itype==s_matrix) { getmatrix(hd,&r,&c,&m); hd1=new_matrix(c,r,""); if (error) return; m1=matrixof(hd1); for (i=0; itype==s_cmatrix) { getmatrix(hd,&r,&c,&m); hd1=new_cmatrix(c,r,""); if (error) return; m1=matrixof(hd1); for (i=0; itype==s_imatrix) { getmatrix(hd,&r,&c,&m); hd1=new_imatrix(c,r,""); if (error) return; m1=matrixof(hd1); for (i=0; itype==s_real || hd->type==s_complex || hd->type==s_interval) { hd1=hd; } else { error=24; output("\' not defined for this value!\n"); return; } moveresult(st,hd1); } void msum (header *hd) { header *st=hd,*result; int c,r,i,j; double *m,*mr,s,si,x,y; hd=getvalue(hd); if (error) return; if (hd->type==s_real || hd->type==s_matrix) { getmatrix(hd,&r,&c,&m); result=new_matrix(r,1,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_complex || hd->type==s_cmatrix) { getmatrix(hd,&r,&c,&m); result=new_cmatrix(r,1,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_interval || hd->type==s_imatrix) { getmatrix(hd,&r,&c,&m); result=new_imatrix(r,1,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_real || hd->type==s_matrix) { getmatrix(hd,&r,&c,&m); result=new_matrix(r,1,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_complex || hd->type==s_cmatrix) { getmatrix(hd,&r,&c,&m); result=new_cmatrix(r,1,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_interval || hd->type==s_imatrix) { getmatrix(hd,&r,&c,&m); result=new_imatrix(r,1,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_real || hd->type==s_matrix) { getmatrix(hd,&r,&c,&m); if (c<1) result=new_matrix(r,1,""); else result=new_matrix(r,c,""); if (error) return; mr=matrixof(result); for (i=0; i=1) sum=*m++; *mr++=sum; for (j=1; jtype==s_complex || hd->type==s_cmatrix) { getmatrix(hd,&r,&c,&m); if (c<1) result=new_cmatrix(r,1,""); else result=new_cmatrix(r,c,""); if (error) return; mr=matrixof(result); for (i=0; i=1) { sumr=*m++; sumi=*m++; } *mr++=sumr; *mr++=sumi; for (j=1; jtype==s_real || hd->type==s_matrix) { getmatrix(hd,&r,&c,&m); if (c<1) result=new_matrix(r,1,""); else result=new_matrix(r,c,""); if (error) return; mr=matrixof(result); for (i=0; i=1) sum=*m++; *mr++=sum; for (j=1; jtype==s_complex || hd->type==s_cmatrix) { getmatrix(hd,&r,&c,&m); if (c<1) result=new_cmatrix(r,1,""); else result=new_cmatrix(r,c,""); if (error) return; mr=matrixof(result); for (i=0; i=1) { sumr=*m++; sumi=*m++; } *mr++=sumr; *mr++=sumi; for (j=1; jtype==s_interval || hd->type==s_imatrix) { getmatrix(hd,&r,&c,&m); if (c<1) result=new_imatrix(r,1,""); else result=new_imatrix(r,c,""); if (error) return; mr=matrixof(result); for (i=0; i=1) { sumr=*m++; sumi=*m++; } *mr++=sumr; *mr++=sumi; for (j=1; jtype==s_interval || hd->type==s_imatrix) { getmatrix(hd,&r,&c,&m); if (c<1) result=new_imatrix(r,1,""); else result=new_imatrix(r,c,""); if (error) return; mr=matrixof(result); for (i=0; i=1) { sumr=*m++; sumi=*m++; } *mr++=sumr; *mr++=sumi; for (j=1; jtype==s_real || hd->type==s_complex || hd->type==s_interval) { moveresult(st,hd); return; } else if (hd->type==s_matrix) { getmatrix(hd,&r,&c,&m); result=new_matrix(r,c,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_cmatrix) { getmatrix(hd,&r,&c,&m); result=new_cmatrix(r,c,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_imatrix) { getmatrix(hd,&r,&c,&m); result=new_imatrix(r,c,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_real || hd->type==s_complex || hd->type==s_interval) { moveresult(st,hd); return; } else if (hd->type==s_matrix) { getmatrix(hd,&r,&c,&m); result=new_matrix(r,c,""); if (error) return; mr=matrixof(result); mr+=(long)(r-1)*c; for (i=0; itype==s_cmatrix) { getmatrix(hd,&r,&c,&m); result=new_cmatrix(r,c,""); if (error) return; mr=matrixof(result); mr+=2l*(long)(r-1)*c; for (i=0; itype==s_imatrix) { getmatrix(hd,&r,&c,&m); result=new_imatrix(r,c,""); if (error) return; mr=matrixof(result); mr+=2l*(long)(r-1)*c; for (i=0; itype==s_real || hd->type==s_complex || hd->type==s_interval) { moveresult(st,hd); return; } else if (hd->type==s_matrix) { getmatrix(hd,&r,&c,&m); result=new_matrix(r,c,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_cmatrix) { getmatrix(hd,&r,&c,&m); result=new_cmatrix(r,c,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_imatrix) { getmatrix(hd,&r,&c,&m); result=new_imatrix(r,c,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_real || hd->type==s_complex || hd->type==s_interval) { moveresult(st,hd); return; } else if (hd->type==s_matrix) { getmatrix(hd,&r,&c,&m); result=new_matrix(r,c,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_cmatrix) { getmatrix(hd,&r,&c,&m); result=new_cmatrix(r,c,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_imatrix) { getmatrix(hd,&r,&c,&m); result=new_imatrix(r,c,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_real || hd->type==s_complex || hd->type==s_interval) { moveresult(st,hd); return; } else if (hd->type==s_matrix) { getmatrix(hd,&r,&c,&m); result=new_matrix(r,c,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_cmatrix) { getmatrix(hd,&r,&c,&m); result=new_cmatrix(r,c,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_imatrix) { getmatrix(hd,&r,&c,&m); result=new_imatrix(r,c,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_real || hd->type==s_complex || hd->type==s_interval) { moveresult(st,hd); return; } else if (hd->type==s_matrix) { getmatrix(hd,&r,&c,&m); result=new_matrix(r,c,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_cmatrix) { getmatrix(hd,&r,&c,&m); result=new_cmatrix(r,c,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_imatrix) { getmatrix(hd,&r,&c,&m); result=new_imatrix(r,c,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_real || hd->type==s_matrix) { if (hd1->type==s_real || hd1->type==s_matrix) { getmatrix(hd,&r,&c,&m); getmatrix(hd1,&r1,&c1,&m1); if (r!=0 && (c!=c1 || (long)r+r1>INT_MAX)) wrong_arg(); result=new_matrix(r+r1,c1,""); if (r!=0) { size=(long)r*c*sizeof(double); memmove((char *)matrixof(result),(char *)m, size); } memmove((char *)matrixof(result)+size, (char *)m1,(long)r1*c1*sizeof(double)); } else if (hd1->type==s_complex || hd1->type==s_cmatrix) { make_complex(st); mvconcat(st); return; } else if (hd1->type==s_interval || hd1->type==s_imatrix) { make_interval(st); mvconcat(st); return; } else wrong_arg(); } else if (hd->type==s_complex || hd->type==s_cmatrix) { if (hd1->type==s_complex || hd1->type==s_cmatrix) { getmatrix(hd,&r,&c,&m); getmatrix(hd1,&r1,&c1,&m1); if (r!=0 && (c!=c1 || (long)r+r1>INT_MAX)) wrong_arg(); result=new_cmatrix(r+r1,c1,""); if (r!=0) { size=(long)r*(long)2*c*sizeof(double); memmove((char *)matrixof(result),(char *)m, size); } memmove((char *)matrixof(result)+size, (char *)m1,(long)r1*(long)2*c1*sizeof(double)); } else if (hd1->type==s_real || hd1->type==s_matrix) { make_complex(next_param(st)); mvconcat(st); return; } else wrong_arg(); } else if (hd->type==s_interval || hd->type==s_imatrix) { if (hd1->type==s_interval || hd1->type==s_imatrix) { getmatrix(hd,&r,&c,&m); getmatrix(hd1,&r1,&c1,&m1); if (r!=0 && (c!=c1 || (long)r+r1>INT_MAX)) wrong_arg(); result=new_imatrix(r+r1,c1,""); if (r!=0) { size=(long)r*(long)2*c*sizeof(double); memmove((char *)matrixof(result),(char *)m, size); } memmove((char *)matrixof(result)+size, (char *)m1,(long)r1*(long)2*c1*sizeof(double)); } else if (hd1->type==s_real || hd1->type==s_matrix) { make_interval(next_param(st)); mvconcat(st); return; } else wrong_arg(); } else wrong_arg(); moveresult(st,result); } void mhconcat (header *hd) { header *st=hd,*hd1,*result; double *m,*m1,*mr; int r,c,r1,c1,i; hd=getvalue(hd); hd1=next_param(st); if (!hd1) wrong_arg(); hd1=getvalue(hd1); if (error) return; if (hd->type==s_string && hd1->type==s_string) { result=new_string(stringof(hd), strlen(stringof(hd))+strlen(stringof(hd1))+1,""); strcat(stringof(result),stringof(hd1)); } else if (hd->type==s_real || hd->type==s_matrix) { if (hd1->type==s_real || hd1->type==s_matrix) { getmatrix(hd,&r,&c,&m); getmatrix(hd1,&r1,&c1,&m1); if (c!=0 && (r!=r1 || (long)c+c1>INT_MAX)) wrong_arg(); result=new_matrix(r1,c+c1,""); mr=matrixof(result); for (i=0; itype==s_complex || hd1->type==s_cmatrix) { make_complex(st); mhconcat(st); return; } else if (hd1->type==s_interval || hd1->type==s_imatrix) { make_interval(st); mhconcat(st); return; } else wrong_arg(); } else if (hd->type==s_complex || hd->type==s_cmatrix) { if (hd1->type==s_complex || hd1->type==s_cmatrix) { getmatrix(hd,&r,&c,&m); getmatrix(hd1,&r1,&c1,&m1); if (c!=0 && (r!=r1 || (long)c+c1>INT_MAX)) wrong_arg(); result=new_cmatrix(r1,c+c1,""); mr=matrixof(result); for (i=0; itype==s_real || hd1->type==s_matrix) { make_complex(next_param(st)); if (error) return; mhconcat(st); return; } else wrong_arg(); } else if (hd->type==s_interval || hd->type==s_imatrix) { if (hd1->type==s_interval || hd1->type==s_imatrix) { getmatrix(hd,&r,&c,&m); getmatrix(hd1,&r1,&c1,&m1); if (c!=0 && (r!=r1 || (long)c+c1>INT_MAX)) wrong_arg(); result=new_imatrix(r1,c+c1,""); mr=matrixof(result); for (i=0; itype==s_real || hd1->type==s_matrix) { make_interval(next_param(st)); if (error) return; mhconcat(st); return; } else wrong_arg(); } else wrong_arg(); moveresult(st,result); } /**************************************************************************** * comparing * ****************************************************************************/ void mscompare (header *hd) { header *st=hd,*hd1,*result; hd=getvalue(hd); hd1=getvalue(nextof(st)); if (error) return; if (hd->type==s_string && hd1->type==s_string) { result=new_real(strcmp(stringof(hd),stringof(hd1)),""); if (error) return; } else wrong_arg(); moveresult(st,result); } void mfind (header *hd) { header *st=hd,*hd1,*result; double *m,*m1,*mr; int i,j,k,c,r,c1,r1; hd=getvalue(hd); hd1=getvalue(nextof(st)); if (error) return; if ((hd->type!=s_matrix && hd->type!=s_real) || (hd1->type!=s_matrix && hd1->type!=s_real)) wrong_arg(); getmatrix(hd,&c,&r,&m); getmatrix(hd1,&c1,&r1,&m1); if (c!=1 && r!=1) wrong_arg(); if (r!=1) c=r; result=new_matrix(c1,r1,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_real || hd->type==s_matrix) { getmatrix(hd,&r,&c,&m); result=new_matrix(r,4,""); if (error) return; mr=matrixof(result); for (i=0; imax) { max=x; imax=j; } } *mr++=min; *mr++=imin+1; *mr++=max; *mr++=imax+1; } } else wrong_arg_in("extrema"); moveresult(st,result); } void many (header *hd) { header *st=hd,*result; int c,r,res=0; long i,n; double *m; hd=getvalue(hd); if (error) return; if (hd->type==s_real || hd->type==s_matrix) { getmatrix(hd,&r,&c,&m); n=(long)(c)*r; } else if (hd->type==s_complex || hd->type==s_cmatrix) { getmatrix(hd,&r,&c,&m); n=(long)2*(long)(c)*r; } else wrong_arg_in("any"); for (i=0; itype!=s_real && hd->type!=s_matrix) wrong_arg_in("nonzeros"); getmatrix(hd,&r,&c,&m); if (r!=1 && c!=1) wrong_arg_in("nonzeros"); if (c==1) c=r; result=new_matrix(1,c,""); if (error) return; k=0; mr=matrixof(result); for (i=0; ic=k; result->size=matrixsize(1,k); moveresult(st,result); } /**************************************************************************** * misc * ****************************************************************************/ void cscalp (double *s, double *si, double *x, double *xi, double *y, double *yi); void ccopy (double *y, double *x, double *xi); void wmultiply (header *hd) /***** multiply matrix multiplication for weakly nonzero matrices. *****/ { header *result,*st=hd,*hd1; dims *d,*d1; double *m,*m1,*m2,*mm1,*mm2,x,y,null=0.0; int i,j,c,r,k; hd=getvalue(hd); hd1=getvalue(nextof(st)); if (error) return; if (hd->type==s_matrix && hd1->type==s_matrix) { d=dimsof(hd); d1=dimsof(hd1); if (d->c != d1->r) { error=8; output("Cannot multiply these!\n"); return; } r=d->r; c=d1->c; result=new_matrix(r,c,""); if (error) return; m=matrixof(result); m1=matrixof(hd); m2=matrixof(hd1); for (i=0; ic,i,0); mm2=m2+j; x=0.0; for (k=0; kc; k++) { if ((*mm1!=0.0)&&(*mm2!=0.0)) x+=(*mm1)*(*mm2); mm1++; mm2+=d1->c; } *mat(m,c,i,j)=x; } moveresult(st,result); return; } if (hd->type==s_matrix && hd1->type==s_cmatrix) { d=dimsof(hd); d1=dimsof(hd1); if (d->c != d1->r) { error=8; output("Cannot multiply these!\n"); return; } r=d->r; c=d1->c; result=new_cmatrix(r,c,""); if (error) return; m=matrixof(result); m1=matrixof(hd); m2=matrixof(hd1); for (i=0; ic,i,0); mm2=m2+(long)2*j; x=0.0; y=0.0; for (k=0; kc; k++) { if ((*mm2!=0.0 || *(mm2+1)!=0.0) && (*mm1!=0.0)) cscalp(&x,&y,mm1,&null,mm2,mm2+1); mm1++; mm2+=2*d1->c; } ccopy(cmat(m,c,i,j),&x,&y); } moveresult(st,result); return; } if (hd->type==s_cmatrix && hd1->type==s_matrix) { d=dimsof(hd); d1=dimsof(hd1); if (d->c != d1->r) { error=8; output("Cannot multiply these!\n"); return; } r=d->r; c=d1->c; result=new_cmatrix(r,c,""); if (error) return; m=matrixof(result); m1=matrixof(hd); m2=matrixof(hd1); for (i=0; ic,i,0); mm2=m2+j; x=0.0; y=0.0; for (k=0; kc; k++) { if ((*mm2!=0.0) && (*mm1!=0.0 || *(mm1+1)!=0.0)) cscalp(&x,&y,mm1,mm1+1,mm2,&null); mm1+=2; mm2+=d1->c; } ccopy(cmat(m,c,i,j),&x,&y); } moveresult(st,result); return; } if (hd->type==s_cmatrix && hd1->type==s_cmatrix) { d=dimsof(hd); d1=dimsof(hd1); if (d->c != d1->r) { error=8; output("Cannot multiply these!\n"); return; } r=d->r; c=d1->c; result=new_cmatrix(r,c,""); if (error) return; m=matrixof(result); m1=matrixof(hd); m2=matrixof(hd1); for (i=0; ic,i,0); mm2=m2+(long)2*j; x=0.0; y=0.0; for (k=0; kc; k++) { if ((*mm2!=0.0 || *(mm2+1)!=0.0) && (*mm1!=0.0 || *(mm1+1)!=0.0)) cscalp(&x,&y,mm1,mm1+1,mm2,mm2+1); mm1+=2; mm2+=2*d1->c; } ccopy(cmat(m,c,i,j),&x,&y); } moveresult(st,result); return; } else wrong_arg(); } void smultiply (header *hd) /***** multiply matrix multiplication for weakly nonzero symmetric matrices. *****/ { header *result,*st=hd,*hd1; dims *d,*d1; double *m,*m1,*m2,*mm1,*mm2,x,y,null=0.0; int i,j,c,r,k; hd=getvalue(hd); hd1=getvalue(nextof(st)); if (error) return; if (hd->type==s_matrix && hd1->type==s_matrix) { d=dimsof(hd); d1=dimsof(hd1); if (d->c != d1->r) { error=8; output("Cannot multiply these!\n"); return; } r=d->r; c=d1->c; result=new_matrix(r,c,""); if (error) return; m=matrixof(result); m1=matrixof(hd); m2=matrixof(hd1); for (i=0; ic,i,0); mm2=m2+j; x=0.0; for (k=0; kc; k++) { if ((*mm1!=0.0)&&(*mm2!=0.0)) x+=(*mm1)*(*mm2); mm1++; mm2+=d1->c; } *mat(m,c,i,j)=x; *mat(m,c,j,i)=x; } moveresult(st,result); return; } if (hd->type==s_matrix && hd1->type==s_cmatrix) { d=dimsof(hd); d1=dimsof(hd1); if (d->c != d1->r) { error=8; output("Cannot multiply these!\n"); return; } r=d->r; c=d1->c; result=new_cmatrix(r,c,""); if (error) return; m=matrixof(result); m1=matrixof(hd); m2=matrixof(hd1); for (i=0; ic,i,0); mm2=m2+(long)2*j; x=0.0; y=0.0; for (k=0; kc; k++) { if ((*mm2!=0.0 || *(mm2+1)!=0.0) && (*mm1!=0.0)) cscalp(&x,&y,mm1,&null,mm2,mm2+1); mm1++; mm2+=2*d1->c; } ccopy(cmat(m,c,i,j),&x,&y); y=-y; ccopy(cmat(m,c,j,i),&x,&y); } moveresult(st,result); return; } if (hd->type==s_cmatrix && hd1->type==s_matrix) { d=dimsof(hd); d1=dimsof(hd1); if (d->c != d1->r) { error=8; output("Cannot multiply these!\n"); return; } r=d->r; c=d1->c; result=new_cmatrix(r,c,""); if (error) return; m=matrixof(result); m1=matrixof(hd); m2=matrixof(hd1); for (i=0; ic,i,0); mm2=m2+j; x=0.0; y=0.0; for (k=0; kc; k++) { if ((*mm2!=0.0) && (*mm1!=0.0 || *(mm1+1)!=0.0)) cscalp(&x,&y,mm1,mm1+1,mm2,&null); mm1+=2; mm2+=d1->c; } ccopy(cmat(m,c,i,j),&x,&y); y=-y; ccopy(cmat(m,c,j,i),&x,&y); } moveresult(st,result); return; } if (hd->type==s_cmatrix && hd1->type==s_cmatrix) { d=dimsof(hd); d1=dimsof(hd1); if (d->c != d1->r) { error=8; output("Cannot multiply these!\n"); return; } r=d->r; c=d1->c; result=new_cmatrix(r,c,""); if (error) return; m=matrixof(result); m1=matrixof(hd); m2=matrixof(hd1); for (i=0; ic,i,0); mm2=m2+(long)2*j; x=0.0; y=0.0; for (k=0; kc; k++) { if ((*mm2!=0.0 || *(mm2+1)!=0.0) && (*mm1!=0.0 || *(mm1+1)!=0.0)) cscalp(&x,&y,mm1,mm1+1,mm2,mm2+1); mm1+=2; mm2+=2*d1->c; } ccopy(cmat(m,c,i,j),&x,&y); y=-y; ccopy(cmat(m,c,j,i),&x,&y); } moveresult(st,result); return; } else wrong_arg(); }