For COO, you have to set three array elements for each entry: the row and column indices as well as the value. You can create a matrix like the one you describe using code like this for COO:
int n = 10, i = 0, r;
cusp::csr_matrix<int,float,cusp::host_memory> A(n, n, 3*n - 4);
// row 0
A.row_indices[i] = 0;
A.column_indices[i] = 0;
A.values[i] = 1.00;
++i;
// rows 1 through n - 2
for (r = 1; r != n - 1; ++r) {
A.row_indices[i] = r;
A.column_indices[i] = r - 1;
A.values[i] = -0.45;
++i;
A.row_indices[i] = r;
A.column_indices[i] = r;
A.values[i] = 0.10;
++i;
A.row_indices[i] = r;
A.column_indices[i] = r + 1;
A.values[i] = -0.45;
++i;
}
// row n - 1
A.row_indices[i] = n - 1;
A.column_indices[i] = n - 1;
A.values[i] = 1.00;
++i;
For CSR you have to specify a column and a value for every entry, and also the index of the first entry for every row including a one-past-the-end index for the one-past-the-end row. A similar piece of code for CSR:
int n = 10, i = 0, r = 0;
cusp::csr_matrix<int,float,cusp::host_memory> A(n, n, 3*n - 4);
// row 0
A.row_offsets[r] = i;
A.column_indices[i] = 0;
A.values[i] = 1.00;
++i;
// rows 1 through n - 2
for (++r; r != n - 1; ++r) {
A.row_offsets[r] = i;
A.column_indices[i] = r - 1;
A.values[i] = -0.45;
++i;
A.column_indices[i] = r;
A.values[i] = 0.10;
++i;
A.column_indices[i] = r + 1;
A.values[i] = -0.45;
++i;
}
// row n - 1
A.row_offsets[r] = i;
A.column_indices[i] = r;
A.values[i] = 1.00;
++i;
++r;
A.row_offsets[r] = i;
To “convert” the matrix from some other format, you have to let us know in what form your original data is stored. Conversion from a cusp::array2d
should work by simply passing that array to the constructor. In general, creating the matrix in sparse format in the first place like the code above does will provide better scalability.
Also note that your example matrix is arranged in diagonal bands, so cusp::dia_matrix
would be better suited, both in terms of easy encoding and in terms of better performance. To create such a tridiagonal matrix, you can use the following code:
int n = 10, r = 0;
cusp::dia_matrix<int,float,cusp::host_memory> A(n, n, 3*n - 4, 3);
A.diagonal_offsets[0] = -1;
A.diagonal_offsets[1] = 0;
A.diagonal_offsets[2] = 1;
// row 0
A.values(r,0) = A.values(r,2) = 0.00;
A.values(r,1) = 1.00;
// rows 1 through n - 2
for (++r; r != n - 1; ++r) {
A.values(r,0) = A.values(r,2) = -0.45;
A.values(r,1) = 0.10;
}
// row n - 1
A.values(r,0) = A.values(r,2) = 0.00;
A.values(r,1) = 1.00;
About this linear equation you try to solve: could it be that octave is operating on a different matrix than the one you pasted into your question? Because with sage I get negative numbers in the result as well:
n = 10
d = dict()
d[(0,0)] = d[(n-1, n-1)] = 1
for r in range(1, n-1):
d[(r, r-1)] = d[(r, r+1)] = -45/100
d[(r,r)] = 1/10
A = matrix(RDF, n, n, d)
b = vector(RDF, [
0.00000,
0.34202,
0.64279,
0.86603,
0.98481,
0.98481,
0.86603,
0.64279,
0.34202,
0.00000,
])
for i in A.solve_right(b):
print('{:+.5f}'.format(float(i)))
gives the following vector x:
+0.00000
-0.45865
-0.86197
-1.16132
-1.32062
-1.32062
-1.16132
-0.86197
-0.45865
+0.00000