## Modelica_LinearSystems2.WorkInProgress.Math.LAPACK

### Package Content

Name | Description
--- | ---
zungqr |
zgeqrf |
zgesvd | Determine singular values of a complex matrix
zgesv | Solve complex system of linear equations A*X=B
zgerq2 |
zgetrf |
zgetri |
zungrq |
zunmrq |
wrapper_zungqr |
wrapper_zgeqrf |
wrapper_zgesvd |
wrapper_zgesv |
wrapper_zgetrf |
wrapper_zgetri |
wrapper_zgerq2 | Wrapper for lapack function zgerq2
wrapper_zungrq |
wrapper_zunmrq | Wrapper for lapack function zunmrq

## Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.zungqr

### Inputs

Type | Name | Default | Description
--- | --- | --- | ---
Complex | QR[:, :] |  | Square or rectangular matrix
Complex | tau[:] |  | elementary reflectors

### Outputs

Type | Name | Description
--- | --- | ---
Complex | Q[size(QR, 1), size(QR, 2)] | matrix Q

### Modelica definition

    function zungqr
      import Modelica_LinearSystems2.Math.Complex;

      input Modelica_LinearSystems2.Math.Complex QR[:,:]
        "Square or rectangular matrix";
      input Complex tau[:] "elementary reflectors";
      output Complex Q[size(QR, 1),size(QR, 2)] "matrix Q";
    protected
      Integer m=size(QR, 1);
      Integer n=size(QR, 2);

      Real QR_real[size(QR, 1),size(QR, 2)]=QR[:,:].re
        "QR factorization in packed format, real part";
      Real QR_imag[size(QR, 1),size(QR, 2)]=QR[:,:].im
        "QR factorization in packed format, imaginary part";
      Real tau_real[min(size(QR, 1), size(QR, 2))]=tau[:].re
        "The scalar factors of the elementary reflectors of Q, real part";
      Real tau_imag[min(size(QR, 1), size(QR, 2))]=tau[:].im
        "The scalar factors of the elementary reflectors of Q, imaginary part";
      Real Q_real[size(QR, 1),size(QR, 2)]
        "matrix Q from QR factorization in packed format, real part";
      Real Q_imag[size(QR, 1),size(QR, 2)]
        "matrix Q from QR factorization in packed format, imaginary part";

    algorithm
      (Q_real,Q_imag) := Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.wrapper_zungqr(
                                      QR_real, QR_imag, tau_real, tau_imag);
      for l1 in 1:m loop
        for l2 in 1:n loop
          Q[l1, l2] := Complex(Q_real[l1, l2],Q_imag[l1, l2]);
        end for;
      end for;

    end zungqr;

## Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.zgeqrf

### Inputs

Type | Name | Default | Description
--- | --- | --- | ---
Complex | A[:, :] |  | Square or rectangular matrix

### Outputs

Type | Name | Description
--- | --- | ---
Complex | Q[size(A, 1), size(A, 2)] | Square upper triangular matrix
Complex | R[size(A, 2), size(A, 2)] | Square upper triangular matrix

### Modelica definition

    function zgeqrf
      import Modelica_LinearSystems2.Math.Complex;

      input Modelica_LinearSystems2.Math.Complex A[:,:]
        "Square or rectangular matrix";
      output Complex Q[size(A, 1),size(A, 2)] "Square upper triangular matrix";
      output Complex R[size(A, 2),size(A, 2)] "Square upper triangular matrix";

    protected
      Integer m=size(A, 1);
      Integer n=size(A, 2);
      Integer info;
      Complex QR[size(A, 1),size(A, 2)] "QR factorization in packed format";
      Real A_real[size(A, 1),size(A, 2)]=A[:, :].re "Square or rectangular matrix";
      Real A_imag[size(A, 1),size(A, 2)]=A[:, :].im "Square or rectangular matrix";
      Real QR_real[size(A, 1),size(A, 2)]
        "QR factorization in packed format, real part";
      Real QR_imag[size(A, 1),size(A, 2)]
        "QR factorization in packed format, imaginary part";
      Real Q_real[size(A, 1),size(A, 2)]
        "QR factorization in packed format, real part";
      Real Q_imag[size(A, 1),size(A, 2)]
        "QR factorization in packed format, imaginary part";
      Real tau_real[min(size(A, 1), size(A_real, 2))]
        "The scalar factors of the elementary reflectors of Q, real part";
      Real tau_imag[min(size(A, 1), size(A_real, 2))]
        "The scalar factors of the elementary reflectors of Q, imaginary part";
    //  Complex tau[:] "The scalar factors of the elementary reflectors of Q";

    algorithm
    assert(m >= n, "\nInput matrix A[" + String(m) + "," + String(n) + "] has more columns as rows.
    This is not allowed when calling Modelica.Matrices.C_QR(A).");
      (QR_real,QR_imag,tau_real,tau_imag,info) := Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.wrapper_zgeqrf(
                                                               A_real, A_imag);
      for l1 in 1:m loop
        for l2 in 1:n loop
          QR[l1, l2] := Complex(QR_real[l1, l2], QR_imag[l1, l2]);
        end for;
      end for;

    //  tau := fill(Complex(0), size(tau_real, 1));
    //   for i in 1:min(m, n) loop
    //     tau[i] := Complex(tau_real[i], tau_imag[i]);
    //   end for;

    // determine R
      R := fill(
        Complex(0),
        n,
        n);
      for i in 1:min(m, n) loop
        for j in i:n loop
          R[i, j] := QR[i, j];
        end for;
      end for;

      (Q_real,Q_imag, info) := Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.wrapper_zungqr(
                                            QR_real, QR_imag, tau_real, tau_imag);
      for l1 in 1:m loop
        for l2 in 1:n loop
          Q[l1, l2] := Complex(Q_real[l1, l2], Q_imag[l1, l2]);
        end for;
      end for;

    end zgeqrf;

## Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.zgesvd

Determine singular values of a complex matrix

### Inputs

Type | Name | Default | Description
--- | --- | --- | ---
Complex | A[:, :] |  | Square or rectangular matrix

### Outputs

Type | Name | Description
--- | --- | ---
Real | sigma[min(size(A, 1), size(A, 2))] | singular values
Complex | U[size(A, 1), size(A, 1)] | Left orthogonal matrix
Complex | VT[size(A, 2), size(A, 2)] | Transposed right orthogonal matrix
Integer | info |

### Modelica definition

    function zgesvd "Determine singular values of a complex matrix"
      import Modelica_LinearSystems2.Math.Complex;
      import Modelica_LinearSystems2.Math.Matrices;

      input Complex A[:,:] "Square or rectangular matrix";
      output Real sigma[min(size(A, 1), size(A, 2))] "singular values";
      output Complex U[size(A, 1),size(A, 1)] "Left orthogonal matrix";
      output Complex VT[size(A, 2),size(A, 2)] "Transposed right orthogonal matrix";
      output Integer info;

    protected
      Integer n=min(size(A, 1), size(A, 2)) "Number of singular values";

      Real U_real[size(A, 1),size(A, 1)] "Left orthogonal matrix, real part";
      Real U_imag[size(A, 1),size(A, 1)] "Left orthogonal matrix, imaginary part";
      Real VT_real[size(A, 2),size(A, 2)] "Left orthogonal matrix, real part";
      Real VT_imag[size(A, 2),size(A, 2)] "Left orthogonal matrix, imaginary part";
      Real A_real[size(A, 1),size(A, 2)]=A[:, :].re "Real part of matrix A";
      Real A_imag[size(A, 1),size(A, 2)]=A[:, :].im "Imaginary part of matrix A";

    algorithm
      if n > 0 then

        (sigma,U_real,U_imag,VT_real,VT_imag,info) := Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.wrapper_zgesvd(
                                                                                     A_real, A_imag);
        assert(info == 0, "The numerical algorithm to compute the singular value decomposition did not converge");

        for l1 in 1:size(A, 1) loop
          for l2 in 1:size(A, 1) loop
            U[l1, l2] := Complex(U_real[l1, l2], U_imag[l1, l2]);
          end for;
        end for;
        for l1 in 1:size(A, 2) loop
          for l2 in 1:size(A, 2) loop
            VT[l1, l2] := Complex(VT_real[l1, l2], VT_imag[l1, l2]);
          end for;
        end for;

      end if;
    end zgesvd;

## Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.zgesv

Solve complex system of linear equations A*X=B

### Inputs

Type | Name | Default | Description
--- | --- | --- | ---
Complex | A[:, size(A, 1)] |  |
Complex | B[size(A, 1), :] |  |

### Outputs

Type | Name | Description
--- | --- | ---
Complex | X[size(A, 1), size(B, 2)] |
Integer | info |

### Modelica definition

    function zgesv "Solve complex system of linear equations A*X=B"
      import Modelica_LinearSystems2.Math.Complex;
      import Modelica_LinearSystems2.Math.Matrices;

      input Complex A[:,size(A, 1)];
      input Complex B[size(A, 1),:];
      output Complex X[size(A, 1),size(B, 2)]=B;
      output Integer info;

    protected
      Integer n=size(A, 1) "Number of equations";

      Real A_real[size(A, 1),size(A, 2)]=A[:, :].re "Real part of matrix A";
      Real A_imag[size(A, 1),size(A, 2)]=A[:, :].im "Imaginary part of matrix A";
      Real B_real[size(B, 1),size(B, 2)]=B[:, :].re "Real part of matrix B";
      Real B_imag[size(B, 1),size(B, 2)]=B[:, :].im "Imaginary part of matrix B";
      Real X_real[size(X, 1),size(X, 2)] "Real part of matrix X";
      Real X_imag[size(X, 1),size(X, 2)] "Imaginary part of matrix X";

    algorithm
      if n > 0 then
        (X_real,X_imag,info) := Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.wrapper_zgesv(
                                                              A_real, A_imag, B_real, B_imag);
        assert(info == 0, "Solving a linear system of equations with function
    \"Matrices.C_solve2\" is not possible, because the system has either
    no or infinitely many solutions (A is singular).");
        for l1 in 1:size(A, 1) loop
          for l2 in 1:size(B, 2) loop
            X[l1, l2] := Complex(X_real[l1, l2], X_imag[l1, l2]);
          end for;
        end for;
      end if;
    end zgesv;

## Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.zgerq2

### Inputs

Type | Name | Default | Description
--- | --- | --- | ---
Complex | A[:, :] |  | Square or rectangular matrix

### Outputs

Type | Name | Description
--- | --- | ---
Complex | RQ[size(A, 1), size(A, 2)] | RQ factorization in packed format
Complex | tau[:] | elementory reflectors

### Modelica definition

    function zgerq2
      import Modelica_LinearSystems2.Math.Complex;

      input Modelica_LinearSystems2.Math.Complex A[:,:]
        "Square or rectangular matrix";
      output Complex RQ[size(A, 1),size(A, 2)] "RQ factorization in packed format";
      output Complex tau[:] "elementory reflectors";

    protected
      Integer n=size(A, 1);
      Integer m=size(A, 2);
      Integer info;
      Real A_real[size(A, 1),size(A, 2)]=A[:, :].re "Square or rectangular matrix";
      Real A_imag[size(A, 1),size(A, 2)]=A[:, :].im "Square or rectangular matrix";
      Real RQ_real[size(A, 1),size(A, 2)]
        "RQ factorization in packed format, real part";
      Real RQ_imag[size(A, 1),size(A, 2)]
        "RQ factorization in packed format, imag part";
      Real tau_real[min(size(A, 1), size(A, 2))]
        "The scalar factors of the elementary reflectors of Q, real part";
      Real tau_imag[min(size(A, 1), size(A, 2))]
        "The scalar factors of the elementary reflectors of Q, imaginary part";

    algorithm
      (RQ_real,RQ_imag,tau_real,tau_imag,info) := Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.wrapper_zgerq2(
                                                                                                        A_real, A_imag);
      for l1 in 1:n loop
        for l2 in 1:m loop
          RQ[l1, l2] := Complex(RQ_real[l1, l2], RQ_imag[l1, l2]);
        end for;
        end for;

       tau := fill(Complex(0), size(tau_real,1));
       for i in 1:min(m, n) loop
         tau[i] := Complex(tau_real[i], tau_imag[i]);
       end for;
    end zgerq2;

## Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.zgetrf

### Inputs

Type | Name | Default | Description
--- | --- | --- | ---
Complex | A[:, :] |  | Square or rectangular matrix

### Outputs

Type | Name | Description
--- | --- | ---
Complex | LU[size(A, 1), size(A, 2)] |
Integer | pivots[min(size(A, 1), size(A, 2))] | Pivot vector
Integer | info | Information

### Modelica definition

    function zgetrf
      import Modelica_LinearSystems2.Math.Complex;

      input Complex A[:,:] "Square or rectangular matrix";
      output Complex LU[size(A, 1),size(A, 2)];
      output Integer pivots[min(size(A, 1), size(A, 2))] "Pivot vector";
      output Integer info "Information";

    protected
      Integer m=size(A, 1);
      Integer n=size(A, 2);
      Real A_real[size(A, 1),size(A, 2)]=A[:, :].re "Square or rectangular matrix";
      Real A_imag[size(A, 1),size(A, 2)]=A[:, :].im "Square or rectangular matrix";
      Real LU_real[size(A, 1),size(A, 2)]
        "LU factorization in packed format, real part";
      Real LU_imag[size(A, 1),size(A, 2)]
        "LU factorization in packed format, imaginary part";

    algorithm
      (LU_real,LU_imag,pivots,info) := Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.wrapper_zgetrf(
                                                                                                   A_real, A_imag);
      for l1 in 1:m loop
        for l2 in 1:n loop
          LU[l1, l2] := Complex(LU_real[l1, l2], LU_imag[l1, l2]);
        end for;
      end for;

    end zgetrf;

## Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.zgetri

### Inputs

Type | Name | Default | Description
--- | --- | --- | ---
Complex | LU[:, size(LU, 1)] |  | LU factorization of zgetrf of a complex square matrix
Integer | pivots[size(LU, 1)] |  | Pivot vector of zgetrf

### Outputs

Type | Name | Description
--- | --- | ---
Complex | inv[size(LU, 1), size(LU, 2)] |
Integer | info |

### Modelica definition

    function zgetri
      import Modelica_LinearSystems2.Math.Complex;

      input Complex LU[:, size(LU, 1)]
        "LU factorization of zgetrf of a complex square matrix";
      input Integer pivots[size(LU, 1)] "Pivot vector of zgetrf";
      output Complex inv[size(LU, 1),size(LU, 2)];
      output Integer info;

    protected
      Integer m=size(LU, 1);
      Integer n=size(LU, 2);
      Real LU_real[size(LU, 1),size(LU, 2)]=LU[:, :].re
        "LU factorization of zgetrf of a complex square matrix, real part";
      Real LU_imag[size(LU, 1),size(LU, 2)]=LU[:, :].im
        "LU factorization of zgetrf of a complex square matrix, imaginary part";
      Real inv_real[size(LU, 1),size(LU, 2)] "Inverse of matrix P*L*U, real part";
      Real inv_imag[size(LU, 1),size(LU, 2)]
        "Inverse of matrix P*L*U, imaginary part";

    algorithm
      (inv_real,inv_imag,info) := Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.wrapper_zgetri(
                                                                                              LU_real, LU_imag, pivots);

      for l1 in 1:m loop
        for l2 in 1:n loop
          inv[l1, l2] := Complex(inv_real[l1, l2], inv_imag[l1, l2]);
        end for;
      end for;

    end zgetri;

## Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.zungrq

### Inputs

Type | Name | Default | Description
--- | --- | --- | ---
Complex | RQ[:, :] |  | Square or rectangular matrix
Complex | tau[:] |  | elementary reflectors

### Outputs

Type | Name | Description
--- | --- | ---
Complex | Q[size(RQ, 1), size(RQ, 2)] | matrix Q

### Modelica definition

    function zungrq
      import Modelica_LinearSystems2.Math.Complex;

      input Modelica_LinearSystems2.Math.Complex RQ[:,:]
        "Square or rectangular matrix";
      input Complex tau[:] "elementary reflectors";
      output Complex Q[size(RQ, 1),size(RQ, 2)] "matrix Q";
    protected
      Integer m=size(RQ, 1);
      Integer n=size(RQ, 2);

      Real RQ_real[size(RQ, 1),size(RQ, 2)]=RQ[:,:].re
        "RQ factorization in packed format, real part";
      Real RQ_imag[size(RQ, 1),size(RQ, 2)]=RQ[:,:].im
        "RQ factorization in packed format, imaginary part";
      Real tau_real[min(size(RQ, 1), size(RQ, 2))]=tau[:].re
        "The scalar factors of the elementary reflectors of Q, real part";
      Real tau_imag[min(size(RQ, 1), size(RQ, 2))]=tau[:].im
        "The scalar factors of the elementary reflectors of Q, imaginary part";
      Real Q_real[size(RQ, 1),size(RQ, 2)]
        "matrix Q from RQ factorization in packed format, real part";
      Real Q_imag[size(RQ, 1),size(RQ, 2)]
        "matrix Q from RQ factorization in packed format, imaginary part";

    algorithm
      assert(m <= n, "\nInput matrix A[" + String(m) + "," + String(n)
         +"] has more rows as columns. This is not allowed when calling Modelica.Matrices.C_RQ(A).");

      (Q_real,Q_imag) := Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.wrapper_zungrq(
                                                                                     RQ_real, RQ_imag, tau_real, tau_imag);
      for l1 in 1:m loop
        for l2 in 1:n loop
          Q[l1, l2] := Complex(Q_real[l1, l2],Q_imag[l1, l2]);
        end for;
      end for;

    end zungrq;

## Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.zunmrq

### Inputs

Type | Name | Default | Description
--- | --- | --- | ---
Complex | C[:, :] |  | Matrix to multiply with Q
Complex | RQ[:, :] |  | Matrix as a result of zgerq2
Complex | tau[:] |  | elementary reflectors
Boolean | left | true |
Boolean | trans | false |

### Outputs

Type | Name | Description
--- | --- | ---
Complex | CQ[size(C, 1), size(C, 2)] | Matrix product C*Q, Q*C, C*Q**H, Q**H*C

### Modelica definition

    function zunmrq
      import Modelica_LinearSystems2.Math.Complex;

      input Modelica_LinearSystems2.Math.Complex C[:,:] "Matrix to multiply with Q";
      input Modelica_LinearSystems2.Math.Complex RQ[:,:]
        "Matrix as a result of zgerq2";
      input Complex tau[:] "elementary reflectors";
      input Boolean left=true;
      input Boolean trans=false;
      output Complex CQ[size(C, 1),size(C, 2)]
        "Matrix product C*Q, Q*C, C*Q**H, Q**H*C";
    protected
      Integer m=size(C, 1);
      Integer n=size(C, 2);

      Real C_real[size(C, 1),size(C, 2)]=C[:,:].re
        "Real part of matrix to multiply with Q";
      Real C_imag[size(C, 1),size(C, 2)]=C[:,:].im
        "Imag part of matrix to multiply with Q";
      Real RQ_real[size(RQ, 1),size(RQ, 2)]=RQ[:,:].re
        "RQ factorization in packed format, real part";
      Real RQ_imag[size(RQ, 1),size(RQ, 2)]=RQ[:,:].im
        "RQ factorization in packed format, imaginary part";
      Real tau_real[min(size(RQ, 1), size(RQ, 2))]=tau[:].re
        "The scalar factors of the elementary reflectors of Q, real part";
      Real tau_imag[min(size(RQ, 1), size(RQ, 2))]=tau[:].im
        "The scalar factors of the elementary reflectors of Q, imaginary part";
      Real CQ_real[size(CQ, 1),size(CQ, 2)] "Matrix product, real part";
      Real CQ_imag[size(CQ, 1),size(CQ, 2)] "Matrix product, imaginary part";

    algorithm
      (CQ_real,CQ_imag) := Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.wrapper_zunmrq(
                                                                                       RQ_real, RQ_imag, tau_real, tau_imag, C_real, C_imag, left, trans);
      for l1 in 1:m loop
        for l2 in 1:n loop
          CQ[l1, l2] := Complex(CQ_real[l1, l2],CQ_imag[l1, l2]);
        end for;
      end for;

    end zunmrq;

## Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.wrapper_zungqr

### Inputs

Type | Name | Default | Description
--- | --- | --- | ---
Real | QR_real[:, :] |  | Square or rectangular matrix
Real | QR_imag[size(QR_real, 1), size(QR_real, 2)] |  | Square or rectangular matrix
Real | tau_real[min(size(QR_real, 1), size(QR_real, 2))] |  | The scalar factors of the elementary reflectors of Q, real part
Real | tau_imag[min(size(QR_real, 1), size(QR_real, 2))] |  | The scalar factors of the elementary reflectors of Q, imaginary part

### Outputs

Type | Name | Description
--- | --- | ---
Real | Q_real[size(QR_real, 1), size(QR_real, 2)] |
Real | Q_imag[size(QR_real, 1), size(QR_real, 2)] |
Integer | info |

### Modelica definition

    function wrapper_zungqr
      import Modelica_LinearSystems2.Math.Complex;

    //  input Modelica_LinearSystems2.Math.Complex A[ :, :] "Square or rectangular matrix";
      input Real QR_real[ :, :] "Square or rectangular matrix";
      input Real QR_imag[size(QR_real,1), size(QR_real,2)]
        "Square or rectangular matrix";
      input Real tau_real[min(size(QR_real, 1), size(QR_real, 2))]
        "The scalar factors of the elementary reflectors of Q, real part";
      input Real tau_imag[min(size(QR_real, 1), size(QR_real, 2))]
        "The scalar factors of the elementary reflectors of Q, imaginary part";
      output Real Q_real[size(QR_real, 1),size(QR_real, 2)]=QR_real;
      output Real Q_imag[size(QR_real, 1),size(QR_real, 2)]=QR_imag;
      output Integer info;

      external "FORTRAN 77" c_inter_zungqr(size(QR_real, 1), size(QR_real, 2), size(tau_real,1),Q_real, Q_imag, size(QR_real,1), tau_real, tau_imag, info);

    end wrapper_zungqr;

## Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.wrapper_zgeqrf

### Inputs

Type | Name | Default | Description
--- | --- | --- | ---
Real | A_real[:, :] |  | Square or rectangular matrix
Real | A_imag[size(A_real, 1), size(A_real, 2)] |  | Square or rectangular matrix

### Outputs

Type | Name | Description
--- | --- | ---
Real | QR_real[size(A_real, 1), size(A_real, 2)] | QR factorization in packed format, real part
Real | QR_imag[size(A_real, 1), size(A_real, 2)] | QR factorization in packed format, imaginary part
Real | tau_real[min(size(A_real, 1), size(A_real, 2))] | The scalar factors of the elementary reflectors of Q, real part
Real | tau_imag[min(size(A_real, 1), size(A_real, 2))] | The scalar factors of the elementary reflectors of Q, imaginary part
Integer | info |

### Modelica definition

    function wrapper_zgeqrf
      import Modelica_LinearSystems2.Math.Complex;

    //  input Modelica_LinearSystems2.Math.Complex A[ :, :] "Square or rectangular matrix";
      input Real A_real[ :, :] "Square or rectangular matrix";
      input Real A_imag[size(A_real,1), size(A_real,2)]
        "Square or rectangular matrix";
      output Real QR_real[size(A_real, 1), size(A_real, 2)]=A_real
        "QR factorization in packed format, real part";
      output Real QR_imag[size(A_real, 1), size(A_real, 2)]=A_imag
        "QR factorization in packed format, imaginary part";
      output Real tau_real[min(size(A_real, 1), size(A_real, 2))]
        "The scalar factors of the elementary reflectors of Q, real part";
      output Real tau_imag[min(size(A_real, 1), size(A_real, 2))]
        "The scalar factors of the elementary reflectors of Q, imaginary part";
      output Integer info;

    protected
      Integer ncol=size(A_real, 2) "Column dimension of A";
      Integer lwork[2*ncol];
      Real work_real[ncol] "work array real";
      Real work_imag[ncol] "work array imaginary";
      external "FORTRAN 77" c_inter_zgeqrf(size(A_real, 1), ncol, QR_real, QR_imag, size(A_real,1), tau_real, tau_imag, info);

    end wrapper_zgeqrf;

## Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.wrapper_zgesvd

### Inputs

Type | Name | Default | Description
--- | --- | --- | ---
Real | A_real[:, :] |  | Square or rectangular matrix
Real | A_imag[size(A_real, 1), size(A_real, 2)] |  | Square or rectangular matrix

### Outputs

Type | Name | Description
--- | --- | ---
Real | sigma[min(size(A_real, 1), size(A_real, 2))] | singular values
Real | U_real[size(A_real, 1), size(A_real, 1)] |
Real | U_imag[size(A_real, 1), size(A_real, 1)] |
Real | VT_real[size(A_real, 2), size(A_real, 2)] |
Real | VT_imag[size(A_real, 2), size(A_real, 2)] |
Integer | info |

### Modelica definition

    function wrapper_zgesvd

      input Real A_real[:,:] "Square or rectangular matrix";
      input Real A_imag[size(A_real, 1),size(A_real, 2)]
        "Square or rectangular matrix";
      output Real sigma[min(size(A_real, 1), size(A_real, 2))] "singular values";
      output Real U_real[size(A_real, 1),size(A_real, 1)];//=identity(size(A_real, 1)) "Left orthogonal matrix, real part";
      output Real U_imag[size(A_real, 1),size(A_real, 1)];//=zeros(size(A_real, 1), size(A_real, 1)) "Left orthogonal matrix, imaginary part";
      output Real VT_real[size(A_real, 2),size(A_real, 2)];//=identity(size(A_real, 2)) "Left orthogonal matrix, real part";
      output Real VT_imag[size(A_real, 2),size(A_real, 2)];//=zeros(size(A_real, 2),  size(A_real, 2)) "Left orthogonal matrix, imaginary part";
      output Integer info;

    protected
      Integer nrow=size(A_real, 1) "Column dimension of A";
      Integer ncol=size(A_real, 2) "Column dimension of A";
      Real rwork[5*min(nrow, ncol)];
    external"FORTRAN 77" c_inter_zgesvd(
        "A",
        "A",
        size(A_real, 1),
        size(A_real, 2),
        A_real,
        A_imag,
        size(A_real, 1),
        sigma,
        U_real,
        U_imag,
        size(A_real, 1),
        VT_real,
        VT_imag,
        size(A_real, 2),
        rwork,
        info);

    end wrapper_zgesvd;

## Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.wrapper_zgesv

### Inputs

Type | Name | Default | Description
--- | --- | --- | ---
Real | A_real[:, size(A_real, 1)] |  | Square or rectangular matrix
Real | A_imag[size(A_real, 1), size(A_real, 2)] |  | Square or rectangular matrix
Real | B_real[size(A_real, 1), :] |  | Square or rectangular matrix
Real | B_imag[size(B_real, 1), size(B_real, 2)] |  | Square or rectangular matrix

### Outputs

Type | Name | Description
--- | --- | ---
Real | X_real[size(A_real, 1), size(B_real, 2)] |
Real | X_imag[size(A_real, 1), size(B_real, 2)] |
Integer | info |

### Modelica definition

    function wrapper_zgesv

      input Real A_real[:,size(A_real,1)] "Square or rectangular matrix";
      input Real A_imag[size(A_real, 1),size(A_real, 2)]
        "Square or rectangular matrix";
      input Real B_real[size(A_real,1),:] "Square or rectangular matrix";
      input Real B_imag[size(B_real, 1),size(B_real, 2)]
        "Square or rectangular matrix";
      output Real X_real[size(A_real, 1), size(B_real, 2)]=B_real;
      output Real X_imag[size(A_real, 1), size(B_real, 2)]=B_imag;
      output Integer info;

    protected
      Real Awork_real[size(A_real, 1), size(A_real, 1)]=A_real;
      Real Awork_imag[size(A_imag, 1), size(A_imag, 1)]=A_imag;
      Integer ipiv[size(A_real, 1)];

    external"FORTRAN 77" c_inter_zgesv(size(A_real, 1), size(B_real, 2), Awork_real, Awork_imag, size(A_real, 1), ipiv,  X_real,  X_imag, size(A_real, 1), info);

    end wrapper_zgesv;

## Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.wrapper_zgetrf

### Inputs

Type | Name | Default | Description
--- | --- | --- | ---
Real | A_real[:, :] |  | Square or rectangular matrix
Real | A_imag[size(A_real, 1), size(A_real, 2)] |  | Square or rectangular matrix

### Outputs

Type | Name | Description
--- | --- | ---
Real | LU_real[size(A_real, 1), size(A_real, 2)] | LU factorization in packed format, real part
Real | LU_imag[size(A_real, 1), size(A_real, 2)] | LU factorization in packed format, imaginary part
Integer | pivots[min(size(A_real, 1), size(A_real, 2))] | Pivot vector
Integer | info |

### Modelica definition

    function wrapper_zgetrf
      import Modelica_LinearSystems2.Math.Complex;

    //  input Modelica_LinearSystems2.Math.Complex A[ :, :] "Square or rectangular matrix";
      input Real A_real[ :, :] "Square or rectangular matrix";
      input Real A_imag[size(A_real,1), size(A_real,2)]
        "Square or rectangular matrix";
      output Real LU_real[size(A_real, 1), size(A_real, 2)]=A_real
        "LU factorization in packed format, real part";
      output Real LU_imag[size(A_real, 1), size(A_real, 2)]=A_imag
        "LU factorization in packed format, imaginary part";
      output Integer pivots[min(size(A_real, 1), size(A_real, 2))] "Pivot vector";
    //  output Real inv_real[size(LU_real, 1), size(LU_real, 2)]=LU_real "Real part of inverse of matrix P*L*U";
    //  output Real inv_imag[size(LU_imag, 1), size(LU_imag, 2)]=LU_imag "Real part of inverse of matrix P*L*U";

      output Integer info;

      external "FORTRAN 77" c_inter_zgetrf(size(A_real, 1), size(A_real, 2), LU_real, LU_imag, size(A_real,1), pivots, info);

    end wrapper_zgetrf;

## Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.wrapper_zgetri

### Inputs

Type | Name | Default | Description
--- | --- | --- | ---
Real | LU_real[:, :] |  | LU factorization of zgetrf of a square matrix, real part
Real | LU_imag[size(LU_real, 1), size(LU_real, 2)] |  | LU factorization of zgetrf of a square matrix, imaginary part
Integer | pivots[size(LU_real, 1)] |  | Pivot vector of zgetrf

### Outputs

Type | Name | Description
--- | --- | ---
Real | inv_real[size(LU_real, 1), size(LU_real, 2)] | Inverse of matrix P*L*U, real part
Real | inv_imag[size(LU_real, 1), size(LU_real, 2)] | Inverse of matrix P*L*U, imaginary part
Integer | info |

### Modelica definition

    function wrapper_zgetri
      import Modelica_LinearSystems2.Math.Complex;

      input Real LU_real[ :, :]
        "LU factorization of zgetrf of a square matrix, real part";
      input Real LU_imag[size(LU_real,1), size(LU_real,2)]
        "LU factorization of zgetrf of a square matrix, imaginary part";
      input Integer pivots[size(LU_real, 1)] "Pivot vector of zgetrf";
      output Real inv_real[size(LU_real, 1), size(LU_real, 2)]=LU_real
        "Inverse of matrix P*L*U, real part";
      output Real inv_imag[size(LU_real, 1), size(LU_real, 2)]=LU_imag
        "Inverse of matrix P*L*U, imaginary part";
      output Integer info;

      external "FORTRAN 77" c_inter_zgetri(size(LU_real, 1), inv_real, inv_imag, size(LU_real,1), pivots, info);

    end wrapper_zgetri;

## Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.wrapper_zgerq2

Wrapper for lapack function zgerq2

### Inputs

Type | Name | Default | Description
--- | --- | --- | ---
Real | A_real[:, :] |  | Square or rectangular matrix
Real | A_imag[size(A_real, 1), size(A_real, 2)] |  | Square or rectangular matrix

### Outputs

Type | Name | Description
--- | --- | ---
Real | RQ_real[size(A_real, 1), size(A_real, 2)] | RQ factorization in packed format, real part
Real | RQ_imag[size(A_real, 1), size(A_real, 2)] | RQ factorization in packed format, imaginary part
Real | tau_real[min(size(A_real, 1), size(A_real, 2))] | The scalar factors of the elementary reflectors of Q, real part
Real | tau_imag[min(size(A_real, 1), size(A_real, 2))] | The scalar factors of the elementary reflectors of Q, imaginary part
Integer | info |

### Modelica definition

    function wrapper_zgerq2 "Wrapper for lapack function zgerq2"
      import Modelica_LinearSystems2.Math.Complex;

    //  input Modelica_LinearSystems2.Math.Complex A[ :, :] "Square or rectangular matrix";
      input Real A_real[ :, :] "Square or rectangular matrix";
      input Real A_imag[size(A_real,1), size(A_real,2)]
        "Square or rectangular matrix";
      output Real RQ_real[size(A_real, 1), size(A_real, 2)]=A_real
        "RQ factorization in packed format, real part";
      output Real RQ_imag[size(A_real, 1), size(A_real, 2)]=A_imag
        "RQ factorization in packed format, imaginary part";
      output Real tau_real[min(size(A_real, 1), size(A_real, 2))]
        "The scalar factors of the elementary reflectors of Q, real part";
      output Real tau_imag[min(size(A_real, 1), size(A_real, 2))]
        "The scalar factors of the elementary reflectors of Q, imaginary part";
      output Integer info;

    protected
      Integer n=size(A_real, 1) "Row dimension of A";
      Integer m=size(A_real, 2) "Column dimension of A";
      external "FORTRAN 77" c_inter_zgerq2(n, m, RQ_real, RQ_imag, n, tau_real, tau_imag, info);

    end wrapper_zgerq2;

## Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.wrapper_zungrq

### Inputs

Type | Name | Default | Description
--- | --- | --- | ---
Real | RQ_real[:, :] |  | Square or rectangular matrix
Real | RQ_imag[size(RQ_real, 1), size(RQ_real, 2)] |  | Square or rectangular matrix
Real | tau_real[min(size(RQ_real, 1), size(RQ_real, 2))] |  | The scalar factors of the elementary reflectors of Q, real part
Real | tau_imag[min(size(RQ_real, 1), size(RQ_real, 2))] |  | The scalar factors of the elementary reflectors of Q, imaginary part

### Outputs

Type | Name | Description
--- | --- | ---
Real | Q_real[size(RQ_real, 1), size(RQ_real, 2)] |
Real | Q_imag[size(RQ_real, 1), size(RQ_real, 2)] |
Integer | info |

### Modelica definition

    function wrapper_zungrq
      import Modelica_LinearSystems2.Math.Complex;

      input Real RQ_real[ :, :] "Square or rectangular matrix";
      input Real RQ_imag[size(RQ_real,1), size(RQ_real,2)]
        "Square or rectangular matrix";
      input Real tau_real[min(size(RQ_real, 1), size(RQ_real, 2))]
        "The scalar factors of the elementary reflectors of Q, real part";
      input Real tau_imag[min(size(RQ_real, 1), size(RQ_real, 2))]
        "The scalar factors of the elementary reflectors of Q, imaginary part";
      output Real Q_real[size(RQ_real, 1),size(RQ_real, 2)]=RQ_real;
      output Real Q_imag[size(RQ_real, 1),size(RQ_real, 2)]=RQ_imag;
      output Integer info;
    //  Integer info;
      external "FORTRAN 77" c_inter_zungrq(size(RQ_real, 1), size(RQ_real, 2), size(tau_real,1),Q_real, Q_imag, size(RQ_real,1), tau_real, tau_imag, info);

    end wrapper_zungrq;

## Modelica_LinearSystems2.WorkInProgress.Math.LAPACK.wrapper_zunmrq

Wrapper for lapack function zunmrq

### Inputs

Type | Name | Default | Description
--- | --- | --- | ---
Real | RQ_real[:, :] |  | Square or rectangular matrix
Real | RQ_imag[size(RQ_real, 1), size(RQ_real, 2)] |  | Square or rectangular matrix
Real | tau_real[min(size(RQ_real, 1), size(RQ_real, 2))] |  | The scalar factors of the elementary reflectors of Q, real part
Real | tau_imag[min(size(RQ_real, 1), size(RQ_real, 2))] |  | The scalar factors of the elementary reflectors of Q, imaginary part
Real | C_real[:, :] |  |
Real | C_imag[size(C_real, 1), size(C_real, 2)] |  |
Boolean | left | true |
Boolean | trans | false |

### Outputs

Type | Name | Description
--- | --- | ---
Real | QC_real[size(C_real, 1), size(C_real, 2)] |
Real | QC_imag[size(C_real, 1), size(C_real, 2)] |
Integer | info |

### Modelica definition

    function wrapper_zunmrq "Wrapper for lapack function zunmrq"
      import Modelica_LinearSystems2.Math.Complex;

      input Real RQ_real[ :, :] "Square or rectangular matrix";
      input Real RQ_imag[size(RQ_real,1), size(RQ_real,2)]
        "Square or rectangular matrix";
      input Real tau_real[min(size(RQ_real, 1), size(RQ_real, 2))]
        "The scalar factors of the elementary reflectors of Q, real part";
      input Real tau_imag[min(size(RQ_real, 1), size(RQ_real, 2))]
        "The scalar factors of the elementary reflectors of Q, imaginary part";
      input Real C_real[:,:];
      input Real C_imag[size(C_real,1), size(C_real,2)];
      input Boolean left=true;
      input Boolean trans=false;

      output Real QC_real[size(C_real, 1),size(C_real, 2)]=C_real;
      output Real QC_imag[size(C_real, 1),size(C_real, 2)]=C_imag;
      output Integer info;

    protected
      Integer lwork = if left then 2*size(C_real,2) else 2*size(C_real,1);
      Integer dim2=if left then size(C_real,1) else size(C_real,2);
      String side = if left then "L" else "R";
      String herm = if trans then "C" else "N";

      external "FORTRAN 77" c_inter_zunmrq(side, herm,  size(QC_real,1),size(QC_real,2), size(tau_real,1), dim2, RQ_real, RQ_imag,  size(tau_real,1), tau_real, tau_imag, QC_real, QC_imag, size(C_real,1), lwork, info);

    end wrapper_zunmrq;