You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
210 lines
7.1 KiB
210 lines
7.1 KiB
/*
|
|
* Copyright(C) 1999-2020, 2023 National Technology & Engineering Solutions
|
|
* of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with
|
|
* NTESS, the U.S. Government retains certain rights in this software.
|
|
*
|
|
* See packages/seacas/LICENSE for details
|
|
*/
|
|
|
|
#include "defs.h"
|
|
#include <stdio.h> // for NULL
|
|
|
|
/* Sparse linked A(matrix) times x(vector), double precision. */
|
|
void splarax(double *result, /* result of matrix vector multiplication */
|
|
struct vtx_data **mat, /* graph data structure */
|
|
int n, /* number of rows/columns in matrix */
|
|
double *vec, /* vector being multiplied by matrix */
|
|
double *vwsqrt, /* square roots of vertex weights */
|
|
double *work /* work vector from 1-n */
|
|
)
|
|
{
|
|
extern int PERTURB; /* perturb matrix? */
|
|
extern int NPERTURB; /* if so, number of edges to perturb */
|
|
extern double PERTURB_MAX; /* maximum value of perturbation */
|
|
struct vtx_data *mat_i; /* an entry in "mat" */
|
|
double sum; /* sums inner product of matrix-row & vector */
|
|
int *colpntr; /* loops through indices of nonzeros in a row */
|
|
float *wgtpntr; /* loops through values of nonzeros */
|
|
int i, j; /* loop counters */
|
|
double *wrkpntr; /* loops through indices of work vector */
|
|
double *vwsqpntr; /* loops through indices of vwsqrt */
|
|
double *vecpntr; /* loops through indices of vec */
|
|
double *respntr; /* loops through indices of result */
|
|
int last_edge; /* last edge in edge list */
|
|
|
|
if (vwsqrt == NULL) { /* No vertex weights */
|
|
if (mat[1]->ewgts == NULL) { /* No edge weights */
|
|
respntr = result;
|
|
for (i = 1; i <= n; i++) {
|
|
mat_i = mat[i];
|
|
colpntr = mat_i->edges;
|
|
last_edge = mat_i->nedges - 1;
|
|
sum = last_edge * vec[*colpntr++];
|
|
for (j = last_edge; j; j--) {
|
|
sum -= vec[*colpntr++];
|
|
}
|
|
*(++respntr) = sum;
|
|
}
|
|
}
|
|
else { /* Edge weights */
|
|
respntr = result;
|
|
for (i = 1; i <= n; i++) {
|
|
mat_i = mat[i];
|
|
colpntr = mat_i->edges;
|
|
wgtpntr = mat_i->ewgts;
|
|
sum = 0.0;
|
|
for (j = mat_i->nedges; j; j--) {
|
|
sum -= *wgtpntr++ * vec[*colpntr++];
|
|
}
|
|
*(++respntr) = sum; /* -sum if want -Ax */
|
|
}
|
|
}
|
|
if (PERTURB && NPERTURB > 0 && PERTURB_MAX > 0.0) {
|
|
perturb(result, vec);
|
|
}
|
|
}
|
|
else { /* Vertex weights */
|
|
wrkpntr = work;
|
|
vecpntr = vec;
|
|
vwsqpntr = vwsqrt;
|
|
for (i = n; i; i--) {
|
|
*(++wrkpntr) = *(++vecpntr) / *(++vwsqpntr);
|
|
}
|
|
|
|
if (mat[1]->ewgts == NULL) { /* No edge weights. */
|
|
respntr = result;
|
|
for (i = 1; i <= n; i++) {
|
|
mat_i = mat[i];
|
|
colpntr = mat_i->edges;
|
|
last_edge = mat_i->nedges - 1;
|
|
sum = (last_edge)*work[*colpntr++];
|
|
for (j = last_edge; j; j--) {
|
|
sum -= work[*colpntr++];
|
|
}
|
|
*(++respntr) = sum;
|
|
}
|
|
}
|
|
else { /* Edge weights. */
|
|
respntr = result;
|
|
for (i = 1; i <= n; i++) {
|
|
mat_i = mat[i];
|
|
colpntr = mat_i->edges;
|
|
wgtpntr = mat_i->ewgts;
|
|
sum = 0.0;
|
|
for (j = mat_i->nedges; j; j--) {
|
|
sum -= *wgtpntr++ * work[*colpntr++];
|
|
}
|
|
*(++respntr) = sum; /* -sum if want -Ax */
|
|
}
|
|
}
|
|
if (PERTURB && NPERTURB > 0 && PERTURB_MAX > 0.0) {
|
|
perturb(result, work);
|
|
}
|
|
|
|
respntr = result;
|
|
vwsqpntr = vwsqrt;
|
|
for (i = n; i; i--) {
|
|
*(++respntr) /= *(++vwsqpntr);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Sparse linked A(matrix) times x(vector)i, float version. */
|
|
void splarax_float(float *result, /* result of matrix vector multiplication */
|
|
struct vtx_data **mat, /* graph data structure */
|
|
int n, /* number of rows/columns in matrix */
|
|
float *vec, /* vector being multiplied by matrix */
|
|
float *vwsqrt, /* square roots of vertex weights */
|
|
float *work /* work vector from 1-n */
|
|
)
|
|
{
|
|
extern int PERTURB; /* perturb matrix? */
|
|
extern int NPERTURB; /* if so, number of edges to perturb */
|
|
extern double PERTURB_MAX; /* maximum value of perturbation */
|
|
struct vtx_data *mat_i; /* an entry in "mat" */
|
|
double sum; /* sums inner product of matrix-row & vector */
|
|
int *colpntr; /* loops through indices of nonzeros in a row */
|
|
float *wgtpntr; /* loops through values of nonzeros */
|
|
int i, j; /* loop counters */
|
|
float *wrkpntr; /* loops through indices of work vector */
|
|
float *vwsqpntr; /* loops through indices of vwsqrt */
|
|
float *vecpntr; /* loops through indices of vec */
|
|
float *respntr; /* loops through indices of result */
|
|
int last_edge; /* last edge in edge list */
|
|
|
|
if (vwsqrt == NULL) { /* No vertex weights */
|
|
if (mat[1]->ewgts == NULL) { /* No edge weights */
|
|
respntr = result;
|
|
for (i = 1; i <= n; i++) {
|
|
mat_i = mat[i];
|
|
colpntr = mat_i->edges;
|
|
last_edge = mat_i->nedges - 1;
|
|
sum = (last_edge)*vec[*colpntr++];
|
|
for (j = last_edge; j; j--) {
|
|
sum -= vec[*colpntr++];
|
|
}
|
|
*(++respntr) = sum;
|
|
}
|
|
}
|
|
else { /* Edge weights */
|
|
respntr = result;
|
|
for (i = 1; i <= n; i++) {
|
|
mat_i = mat[i];
|
|
colpntr = mat_i->edges;
|
|
wgtpntr = mat_i->ewgts;
|
|
sum = 0.0;
|
|
for (j = mat_i->nedges; j; j--) {
|
|
sum -= *wgtpntr++ * vec[*colpntr++];
|
|
}
|
|
*(++respntr) = sum; /* -sum if want -Ax */
|
|
}
|
|
}
|
|
if (PERTURB && NPERTURB > 0 && PERTURB_MAX > 0.0) {
|
|
perturb_float(result, vec);
|
|
}
|
|
}
|
|
else { /* Vertex weights */
|
|
wrkpntr = work;
|
|
vecpntr = vec;
|
|
vwsqpntr = vwsqrt;
|
|
for (i = n; i; i--) {
|
|
*(++wrkpntr) = *(++vecpntr) / *(++vwsqpntr);
|
|
}
|
|
|
|
if (mat[1]->ewgts == NULL) { /* No edge weights. */
|
|
respntr = result;
|
|
for (i = 1; i <= n; i++) {
|
|
mat_i = mat[i];
|
|
colpntr = mat_i->edges;
|
|
last_edge = mat_i->nedges - 1;
|
|
sum = (last_edge)*work[*colpntr++];
|
|
for (j = last_edge; j; j--) {
|
|
sum -= work[*colpntr++];
|
|
}
|
|
*(++respntr) = sum;
|
|
}
|
|
}
|
|
else { /* Edge weights. */
|
|
respntr = result;
|
|
for (i = 1; i <= n; i++) {
|
|
mat_i = mat[i];
|
|
colpntr = mat_i->edges;
|
|
wgtpntr = mat_i->ewgts;
|
|
sum = 0.0;
|
|
for (j = mat_i->nedges; j; j--) {
|
|
sum -= *wgtpntr++ * work[*colpntr++];
|
|
}
|
|
*(++respntr) = sum; /* -sum if want -Ax */
|
|
}
|
|
}
|
|
if (PERTURB && NPERTURB > 0 && PERTURB_MAX > 0.0) {
|
|
perturb_float(result, work);
|
|
}
|
|
|
|
respntr = result;
|
|
vwsqpntr = vwsqrt;
|
|
for (i = n; i; i--) {
|
|
*(++respntr) /= *(++vwsqpntr);
|
|
}
|
|
}
|
|
}
|
|
|