I want to get array h[16]={16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,}, but I get an error:
If I delete status = vslCorrSetStart(task, h_start); in code, it will work normally, and array h[16]={0,0,0,0,0,16,15,14,0,12,11,10,0,8,7,6}.
What can I do?
#include <assert.h>
#include <mkl.h>
#include <iostream>
using namespace std;
void main()
{
//input
const double f[16] = { 1 , 2 , 3 , 4,
5 , 6 , 7 , 8,
9 , 10, 11, 12,
13, 14, 15, 16,};
//kernel
const double g[9] = { 0, 0, 0,
0, 1, 0,
0, 0, 0 };
//out
double h[16] = { 0 };
VSLCorrTaskPtr task;
MKL_INT f_shape[2] = { 4, 4 };
MKL_INT g_shape[2] = { 3, 3 };
MKL_INT h_shape[2] = { 4, 4 };
MKL_INT h_start[2] = { 1, 1 };
MKL_INT f_stride[2] = { f_shape[1], 1 };
MKL_INT g_stride[2] = { g_shape[1], 1 };
MKL_INT h_stride[2] = { h_shape[1], 1 };
int status;
status = vsldCorrNewTask(&task, VSL_CORR_MODE_DIRECT, 2, f_shape, g_shape, h_shape);
assert(status == VSL_STATUS_OK);
status = vslCorrSetStart(task, h_start);
assert(status == VSL_STATUS_OK);
//always get wrong,return -2303 I can't find the problem
status = vsldCorrExec(task, f, f_stride, g, g_stride, h, h_stride);
assert(status == VSL_STATUS_OK);
status = vslCorrDeleteTask(&task);
assert(status == VSL_STATUS_OK);
//print the result
for (int r = 0; r < 4; r++)
{
cout << r << "(out): ";
for (int c = 0; c < 4; c++)
{
cout << h[r * 4 + c] << " ";
}
cout << endl;
}
}
Related
I am trying to use thrust remove_if and I have some questions. However first, the example in the documentation is not working as it should
Here the code (that contains the doc code too)
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
//#include <thrust/copy.h>
#include <thrust/remove.h>
#include <iostream>
template<typename T>
struct is_zero {
__host__ __device__
auto operator()(T x) const -> bool {
return x == 0;
}
};
struct is_even
{
__host__ __device__
bool operator()(const int x)
{
return (x % 2) == 0;
}
};
int main(void){
int h_data[6] = {1, 0, 2, 0, 1, 3};
const int N = 6;
int A[N] = {1, 4, 2, 8, 5, 7};
int *new_end = thrust::remove_if(A, A + N, is_even());
int * d_data;
cudaMalloc((void**)&d_data, 6 * sizeof(int));
cudaMemcpy(d_data, h_data, 6 * sizeof(int), cudaMemcpyHostToDevice);
thrust::device_ptr<int> dev_ptr(d_data);
thrust::device_vector<int> output;
thrust::remove_if(dev_ptr, dev_ptr+6, is_zero<int>());
//thrust::remove_if(d_data, d_data+6, is_zero<int>()); //--> segmentation fault
cudaMemcpy(h_data, d_data, 6 * sizeof(int), cudaMemcpyDeviceToHost);
for(int i = 0; i < 6; i++)
std::cout << "H[" << i << "] = " << h_data[i]<< std::endl;
for(int i = 0; i < 6; i++)
std::cout << "new_end[" << i << "] = " << new_end[i]<< std::endl;
}
I run this and I got
H[0] = 1
H[1] = 2
H[2] = 1
H[3] = 3
H[4] = 1
H[5] = 3
new_end[0] = 8
new_end[1] = 5
new_end[2] = 7
new_end[3] = -491667200
new_end[4] = 541501445
new_end[5] = 2019959568
In the documentation it is said
// The first three values of A are now {1, 5, 7}
// Values beyond new_end are unspecified
The results of the part programmed seems to be working (if zero)
But the ones in the tutorial are not the results.
I've written a program which is computing the eigenvalues and eigenvectors of a hermitian matrix.
Does anyone know how this is done in GSL properly? Here is what I already have.
//hermitian matrix
0 1 0 -i
1 0 -i 0
0 i 0 1
i 0 1 0
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_blas.h>
#include <gsl/gsl_linalg.h>
#include <gsl/gsl_complex.h>
#include <gsl/gsl_complex_math.h>
#include <gsl/gsl_eigen.h>
using namespace std;
const int N = 4;
int main(){
gsl_eigen_hermv_workspace *workN = gsl_eigen_hermv_alloc(N);
gsl_matrix_complex *A = gsl_matrix_complex_alloc(N, N);
gsl_complex i = gsl_complex_rect(0.0,1.0);
gsl_complex ii = gsl_complex_rect(0.0,-1.0);
gsl_vector *eval = gsl_vector_alloc(N);
gsl_matrix_complex *evec = gsl_matrix_complex_alloc(N, N);
double mTab[] = {
0, 1, 0, 5,
1, 0, 5, 0,
0, 5, 0, 1,
5, 0, 1, 0
};
gsl_matrix_complex_view tmpM = gsl_matrix_complex_view_array(mTab, N, N);
gsl_matrix_complex_memcpy(A, &tmpM.matrix);
gsl_matrix_complex_set(A, 0, 3, ii);
gsl_matrix_complex_set(A, 1, 2, ii);
gsl_matrix_complex_set(A, 2, 1, i);
gsl_matrix_complex_set(A, 3, 0, i);
gsl_eigen_hermv(A, eval, evec, workN);
for(int i=0; i < N; i++){
for(int j=0; j < N; j++){
gsl_complex z = gsl_matrix_complex_get(A, i, j);
cout << GSL_REAL(z) << "+ i" << GSL_IMAG(z) << " ";
}
cout << "\n";
}
cout << "\n";
for(int i=0; i < N; i++){
cout << gsl_vector_get(eval, i) << " ";
}
return 0;
}
This is how I output the eigenvectors
for(int i=0; i < N; i++){
for(int j=0; j < N; j++){
gsl_complex z = gsl_matrix_complex_get(A, i, j);
cout << GSL_REAL(z) << "+ i" << GSL_IMAG(z) << " ";
}
cout << "\n";
}
Finally, here's the way I declared the matrix in question.
double mTab[] = {
0, 1, 0, 5,
1, 0, 5, 0,
0, 5, 0, 1,
5, 0, 1, 0
};
Later, I added the complex numbers.
I managed to print the eigenvectors but I don't know how to do that for the eigenvalues. Any help with that is appreciated?.
You have an error in using the double mTab for gsl_matrix_complex_view_array. This assumes an array of complex numbers represented as real parts followed by imaginary parts in one large array of double values. You can change your definition to:
double mTab[] = {
0, 0, 1, 0, 0, 0, 5, 0,
1, 0, 0, 0, 5, 0, 0, 0,
0, 0, 5, 0, 0, 0, 1, 0,
5, 0, 0, 0, 1, 0, 0, 0,
};
(Which also means you don't need to use a "dummy" variable of 5 just to rewrite it by ±i later.) Then the code for printing eigenvalues works well.
Also you have a typo in the eigenvector printing loop: it should be
gsl_complex z = gsl_matrix_complex_get(evec, i, j);
not
gsl_complex z = gsl_matrix_complex_get(A, i, j);
does any one has a simple C++ code example of using MKL sparse matrix vector multiply routine? I need to use "mkl_zcsrsymv" to multiply a complex symmetric matrix (stored in lower triangular) with a complex vector, but I couldn't find a single demonstrative example on this. Unable to compile my code for complex case.
Read the documentation for mkl_zcsrsymv on Intel's homepage. Here symmetric is to be taken literally! (It does not mean Hermitian)
Compile with icpc -mkl test.c for maximal convenience.
#include <stdio.h>
#include "mkl_spblas.h"
int main()
{
/* Matrix in CRS format
*
* { { 0, 0, i }
* { 0, -1, 2 }
* { i, 2, 0 } }
*/
int m = 3;
MKL_Complex16 a[] = { {0,1}, {-1,0}, {2,0}, {0,1}, {2,0} };
int ia[] = { 0, 1, 3, 5 };
int ja[] = { 2, 1, 2, 0, 1 };
MKL_Complex16 x[] = { {1,0}, {2,0}, {3,0} };
MKL_Complex16 y[] = { {0,0}, {0,0}, {0,0} };
char uplo = 'L';
// Use MKL to compute
// y = A*x
mkl_cspblas_zcsrsymv(&uplo, &m, a, ia, ja, x, y);
printf("y = { (%g,%g), (%g,%g), (%g,%g) }\n",
y[0].real, y[0].imag,
y[1].real, y[1].imag,
y[2].real, y[2].imag
);
}
Output is y = { (0,3), (4,0), (4,1) }. Check it on WolframAlpha.
Here is also an example for mkl_dcsrmv.
#include <stdio.h>
#include "mkl_spblas.h"
int main()
{
/* Matrix in CRS format
*
* { { 0, 0, 1 }
* { 0, -1, 2 }
* { 1, 0, 0 } }
*/
int m = 3;
int k = 3;
double val[] = { 1, -1, 2, 1 };
int indx[] = { 2, 1, 2, 0 };
int pntrb[] = { 0, 1, 3 };
int pntre[] = { 1, 3, 4 };
double x[] = { 1, 2, 3 };
double y[] = { 0, 0, 0 };
double alpha = 1;
double beta = 0;
char transa = 'N';
char matdescra[] = {
'G', // type of matrix
' ', // triangular indicator (ignored in multiplication)
' ', // diagonal indicator (ignored in multiplication)
'C' // type of indexing
};
// Use MKL to compute
// y = alpha*A*x + beta*y
mkl_dcsrmv(&transa, &m, &k, &alpha, matdescra, val, indx, pntrb, pntre, x, &beta, y);
printf("y = { %g, %g, %g }\n", y[0], y[1], y[2]);
}
Output is y = { 3, 4, 1 }. Check it on WolframAlpha.
While playing with this I found out that this is directly compatible with Armadillo. This makes it very convenient to use in C++. Here I first generate a random symmetric matrix with Armadillo and convert it to sparse. This I multiply with a random vector. Finally I compare the result to Armadillo's sparse matrix-vector product. The precision differs quite substantially.
#include <iostream>
#include <armadillo>
#define MKL_Complex16 arma::cx_double
#include "mkl_spblas.h"
int main()
{
/* Matrix in CRS format
*
* { { 0, 0, i }
* { 0, -1, 2 }
* { i, 2, 0 } }
*/
int dim = 1000;
arma::sp_cx_mat a(arma::randu<arma::cx_mat>(dim,dim));
a += a.st();
arma::cx_vec x = arma::randu<arma::cx_vec>(dim);
arma::cx_vec y(dim);
char uplo = 'L';
// Use MKL to compute
// y = A*x
mkl_cspblas_zcsrsymv(&uplo, &dim,
a.values, (int*)a.col_ptrs, (int*)a.row_indices,
x.memptr(), y.memptr());
std::cout << std::boolalpha
<< arma::approx_equal(y, a*x, "absdiff", 1e-10)
<< '\n';
}
I have a k-ary tree stored in a std::vector called tree:
0, 1, 2
3, 4, 5 6, 7, 8 9, 10, 11
12,13,14 15,16,17 18,19,20 21,22,23 24,25,26 27,28,29 30,31,32 33,34,35 36,37,38
tree.size() == 39 as sketched above
I'm searching for a loop similar to following:
for (size_t i=0,j=tree.size(); i!=j; i=some_magic()) // <<---here
{
std::cout << i << std::endl;
}
Which should output:
0
3
12
13
14
4
15
...
For depth-first search you'll need a stack of some kind.
int child(int i, int c) { return (i+1)*3+c; }
int main()
{
std::vector<int> parents = { 2, 1, 0 };
while(!parents.empty())
{
int i = parents.back();
parents.pop_back();
std::cout << tree[i] << std::endl;
for(int c = 0; c != 3; ++c)
{
if(child(i, 2-c) < tree.size())
parents.push_back(child(i, 2-c));
}
}
}
So I'm trying to code Dijkstra's shortest path algorithm in C++. For some reason, it's not adding up the distances correctly...
Here is what I have so far for code. You can ignore the section where I am copying the path to the stack because I know it's not complete yet. Any ideas where I'm going wrong?
#include <fstream>
#include "matrix.h"
#include <list> // STL container
using namespace std;
//---------------------------------------------------------------------------
const int INFIN = 100000;
const int size = 8;
double a[] = {
0, 0, 5, 0, 0, 2, 3, 0, //length matrix ( #9, page 276)
4, 0, 6, 0, 7, 0, 5, 0,
0, 3, 0, 9, 2, 6, 0, 7,
3, 0, 2, 0, 1, 0, 7, 6,
0, 5, 0, 1, 0, 0, 4, 0,
0, 0, 2, 0, 8, 0, 9, 0,
1, 2, 3, 0, 0, 6, 0, 0,
5, 0, 8, 0, 2, 0, 9, 0
};
// Global declarations for L Matrix and begin and end node
Matrix L(size,size,a); //length matrix
int begin, end;
void path(long* D, int* P); //function prototype for shortest path algorithm
Matrix Warshall(Matrix M);
void main()
{
int i, u;
long D [size+1]; //distance functions
int P [size+1]; //prior vertices in path
cout << "\nLength Matrix: " << L;
cout << "\nPaths that exist:" << Warshall(L);
for (i=1; i <= size; i++) {
D[i] = INFIN; //initialize distance functions
P[i] = 0;
}
cout << "\nFind distance from vertex #";
cin >> begin;
cout << " to vertex #";
cin >> end;
if (begin == end) exit(1);
if (begin < 0 || end < 0) exit(1);
if (begin > size || end > size) exit(1);
path(D,P);
cout << "\nShortest distance from \nvertex #"
<< begin << " to vertex #"
<< end << " is " << D[end];
// u = end;
list<int> stack; // work path backwards
while (1) {
stack.push_front(end);
stack.push_front(begin);
break;
}
cout << "\nusing path:\n";
cout << "\t" << stack.front();
stack.pop_front();
while (stack.size()) {
cout << " -> " << stack.front();
stack.pop_front();
}
getch();
}
void path(long* D, int* P) {
int i, u, dist;
int U[size+1];
for (i=1; i <= size; i++)
U[i] = 0;
U[begin] = 1; // add first vertex;
D[begin] = 0;
u = begin;
do { // until find end vertex
for (i = 1; i <= size; i++) {
dist = L.element(u,i); // distance from u to i
if( D[u] + dist < D[i]) {
D[i] = D[u] + dist;
P[i] = u;
}
}
dist = 38000; // reset distance value to large value
int min;
for(i = 1; i <= size; i++) {
if(L.element(u,i) != 0) {
if(L.element(u,i) < dist && U[i] != 1) {
dist = L.element(u,i);
min = i;
}
}
}
u = min;
U[u] = 1;
cout << "Min is " << min << endl;
} while (u != end);
}
if( D[u] + dist < D[i]) {
D[i] = D[u] + dist;
P[i] = u;
}
should be
if( D[u] + dist < D[i] && dist != 0) {
D[i] = D[u] + dist;
P[i] = u;
}