Refactor LD back-substitution (CSR version).
PiperOrigin-RevId: 717403904 Change-Id: Idcd5e71f03a960203c22cb737d399fac5a0ba59c
This commit is contained in:
committed by
Copybara-Service
parent
2a100547bd
commit
5c4c79cd6a
@@ -1609,84 +1609,78 @@ void mj_solveLD(const mjModel* m, mjtNum* restrict x, int n,
|
|||||||
// like mj_solveLD, but using the CSR representation of L
|
// like mj_solveLD, but using the CSR representation of L
|
||||||
void mj_solveLDs(mjtNum* restrict x, const mjtNum* qLDs, const mjtNum* qLDiagInv, int nv, int n,
|
void mj_solveLDs(mjtNum* restrict x, const mjtNum* qLDs, const mjtNum* qLDiagInv, int nv, int n,
|
||||||
const int* rownnz, const int* rowadr, const int* diagnum, const int* colind) {
|
const int* rownnz, const int* rowadr, const int* diagnum, const int* colind) {
|
||||||
// single vector
|
// x <- L^-T x
|
||||||
if (n == 1) {
|
for (int i=nv-1; i > 0; i--) {
|
||||||
// x <- L^-T x
|
// skip diagonal rows
|
||||||
for (int i=nv-1; i > 0; i--) {
|
if (diagnum[i]) {
|
||||||
// skip diagonal rows, zero elements in input vector
|
continue;
|
||||||
mjtNum x_i = x[i];
|
|
||||||
if (x_i == 0 || diagnum[i]) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int start = rowadr[i];
|
|
||||||
int end = start + rownnz[i] - 1;
|
|
||||||
for (int adr=start; adr < end; adr++) {
|
|
||||||
x[colind[adr]] -= qLDs[adr] * x_i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// x <- D^-1 x
|
// one vector
|
||||||
for (int i=0; i < nv; i++) {
|
if (n == 1) {
|
||||||
x[i] *= qLDiagInv[i];
|
mjtNum x_i;
|
||||||
}
|
if ((x_i = x[i])) {
|
||||||
|
int start = rowadr[i];
|
||||||
// x <- L^-1 x
|
int end = start + rownnz[i] - 1;
|
||||||
for (int i=1; i < nv; i++) {
|
for (int adr=start; adr < end; adr++) {
|
||||||
// skip diagonal rows
|
x[colind[adr]] -= qLDs[adr] * x_i;
|
||||||
if (diagnum[i]) {
|
|
||||||
i += diagnum[i] - 1; // iterating forward: skip ahead, adjust i
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int adr = rowadr[i];
|
|
||||||
x[i] -= mju_dotSparse(qLDs+adr, x, rownnz[i] - 1, colind+adr, /*flg_unc1=*/0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// multiple vectors
|
|
||||||
else {
|
|
||||||
// x <- L^-T x
|
|
||||||
for (int i=nv-1; i > 0; i--) {
|
|
||||||
// skip diagonal rows
|
|
||||||
if (diagnum[i]) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int start = rowadr[i];
|
|
||||||
int end = start + rownnz[i] - 1;
|
|
||||||
for (int adr=start; adr < end; adr++) {
|
|
||||||
int j = colind[adr];
|
|
||||||
mjtNum val = qLDs[adr];
|
|
||||||
for (int offset=0; offset < n*nv; offset+=nv) {
|
|
||||||
mjtNum x_i;
|
|
||||||
if ((x_i = x[i+offset])) {
|
|
||||||
x[j+offset] -= val * x_i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// x <- D^-1 x
|
// multiple vectors
|
||||||
for (int i=0; i < nv; i++) {
|
else {
|
||||||
mjtNum invD_i = qLDiagInv[i];
|
int start = rowadr[i];
|
||||||
|
int end = start + rownnz[i] - 1;
|
||||||
|
for (int offset=0; offset < n*nv; offset+=nv) {
|
||||||
|
mjtNum x_i;
|
||||||
|
if ((x_i = x[i+offset])) {
|
||||||
|
for (int adr=start; adr < end; adr++) {
|
||||||
|
x[offset + colind[adr]] -= qLDs[adr] * x_i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// x <- D^-1 x
|
||||||
|
for (int i=0; i < nv; i++) {
|
||||||
|
mjtNum invD_i = qLDiagInv[i];
|
||||||
|
|
||||||
|
// one vector
|
||||||
|
if (n == 1) {
|
||||||
|
x[i] *= invD_i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// multiple vectors
|
||||||
|
else {
|
||||||
for (int offset=0; offset < n*nv; offset+=nv) {
|
for (int offset=0; offset < n*nv; offset+=nv) {
|
||||||
x[i+offset] *= invD_i;
|
x[i+offset] *= invD_i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// x <- L^-1 x
|
// x <- L^-1 x
|
||||||
for (int i=1; i < nv; i++) {
|
for (int i=1; i < nv; i++) {
|
||||||
// skip diagonal rows
|
// skip diagonal rows
|
||||||
if (diagnum[i]) {
|
if (diagnum[i]) {
|
||||||
i += diagnum[i] - 1; // iterating forward: skip ahead, adjust i
|
i += diagnum[i] - 1; // iterating forward: skip ahead, adjust i
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int adr = rowadr[i];
|
||||||
|
int d = rownnz[i] - 1;
|
||||||
|
if (d > 0) {
|
||||||
|
// one vector
|
||||||
|
if (n == 1) {
|
||||||
|
x[i] -= mju_dotSparse(qLDs+adr, x, d, colind+adr, /*flg_unc1=*/0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int adr = rowadr[i];
|
// multiple vectors
|
||||||
int d = rownnz[i] - 1;
|
else {
|
||||||
for (int offset=0; offset < n*nv; offset+=nv) {
|
for (int offset=0; offset < n*nv; offset+=nv) {
|
||||||
x[i+offset] -= mju_dotSparse(qLDs+adr, x+offset, d, colind+adr, /*flg_unc1=*/0);
|
x[i+offset] -= mju_dotSparse(qLDs+adr, x+offset, d, colind+adr, /*flg_unc1=*/0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user