bridge/class-master/depend/pari/src/basemath/alglin1.c
/* find Z such that A Z = B. Return NULL if no solution */
find Z such that A Z = B. Return NULL if no solution
find Z such that A Z = B . Return NULL if no solution
GEN
RgM_invimage(GEN A, GEN B)
{
  pari_sp av = avma;
  GEN d, x, X, Y;
  long i, j, nY, nA = lg(A)-1, nB = lg(B)-1;
  X = RgM_invimage_fast(A, B);
  if (!X) {avma = av; return NULL; }
  if (X != gen_0) return X;
  x = ker(shallowconcat(RgM_neg(A), B));
  nY = lg(x)-1;
  if (nY < nB) { avma = av; return NULL; }
  Y = rowslice(x, nA+1, nA+nB); 
  d = cgetg(nB+1, t_VECSMALL);
  for (i = nB, j = nY; i >= 1; i--, j--)
  {
    for (; j>=1; j--)
      if (!gequal0(gcoeff(Y,i,j))) { d[i] = j; break; }
    if (!j) { avma = av; return NULL; }
  }
  Y = vecpermute(Y, d);
  x = vecpermute(x, d);
  X = rowslice(x, 1, nA);
  return gerepileupto(av, RgM_mul(X, RgM_inv_upper(Y)));
}
GEN RgM_invimage ( GEN A , GEN B ) { pari_sp av = avma ; GEN d , x , X , Y ; long i , j , nY , nA = lg ( A ) - 1 , nB = lg ( B ) - 1 ; X = RgM_invimage_fast ( A , B ) ; if ( ! X ) { avma = av ; return NULL ; } if ( X != gen_0 ) return X ; x = ker ( shallowconcat ( RgM_neg ( A ) , B ) ) ; nY = lg ( x ) - 1 ; if ( nY < nB ) { avma = av ; return NULL ; } Y = rowslice ( x , nA + 1 , nA + nB ) ; d = cgetg ( nB + 1 , t_VECSMALL ) ; for ( i = nB , j = nY ; i >= 1 ; i -- , j -- ) { for ( ; j >= 1 ; j -- ) if ( ! gequal0 ( gcoeff ( Y , i , j ) ) ) { d [ i ] = j ; break ; } if ( ! j ) { avma = av ; return NULL ; } } Y = vecpermute ( Y , d ) ; x = vecpermute ( x , d ) ; X = rowslice ( x , 1 , nA ) ; return gerepileupto ( av , RgM_mul ( X , RgM_inv_upper ( Y ) ) ) ; }
find Z such that A Z = B.
find Z such that A Z = B .
/* AX = BY, Y in strict upper echelon form with pivots = 1.
   * We must find T such that Y T = Id_nB then X T = Z. This exists iff
   * Y has at least nB columns and full rank */ /* nB rows */ /* reduce to the case Y square, upper triangular with 1s on diagonal */