I have a .csv file:
lp;imie;nazwisko;ulica;numer;kod;miejscowosc;telefon;email;data_ur
1;Jan;Kowalski;ul. Nowa;1a;11-234;Budry;123-123-456;jan#go.xxx;1980.05.13
2;Jerzy;Nowak;ul. Konopnicka;13a/3;00-900;Lichowice;(55)333-44-55;jer#wu.to;1990.03.23
And I need to read this in C. I have some code, but only for the connection.
Hopefully this would get you started
See it live on http://ideone.com/l23He (using stdin)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const char* getfield(char* line, int num)
{
const char* tok;
for (tok = strtok(line, ";");
tok && *tok;
tok = strtok(NULL, ";\n"))
{
if (!--num)
return tok;
}
return NULL;
}
int main()
{
FILE* stream = fopen("input", "r");
char line[1024];
while (fgets(line, 1024, stream))
{
char* tmp = strdup(line);
printf("Field 3 would be %s\n", getfield(tmp, 3));
// NOTE strtok clobbers tmp
free(tmp);
}
}
Output:
Field 3 would be nazwisko
Field 3 would be Kowalski
Field 3 would be Nowak
The following code is in plain c language and handles blank spaces.
It only allocates memory once, so one free() is needed, for each processed line.
http://ideone.com/mSCgPM
/* Tiny CSV Reader */
/* Copyright (C) 2015, Deligiannidis Konstantinos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://w...content-available-to-author-only...u.org/licenses/>. */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* For more that 100 columns or lines (when delimiter = \n), minor modifications are needed. */
int getcols( const char * const line, const char * const delim, char ***out_storage )
{
const char *start_ptr, *end_ptr, *iter;
char **out;
int i; //For "for" loops in the old c style.
int tokens_found = 1, delim_size, line_size; //Calculate "line_size" indirectly, without strlen() call.
int start_idx[100], end_idx[100]; //Store the indexes of tokens. Example "Power;": loc('P')=1, loc(';')=6
//Change 100 with MAX_TOKENS or use malloc() for more than 100 tokens. Example: "b1;b2;b3;...;b200"
if ( *out_storage != NULL ) return -4; //This SHOULD be NULL: Not Already Allocated
if ( !line || !delim ) return -1; //NULL pointers Rejected Here
if ( (delim_size = strlen( delim )) == 0 ) return -2; //Delimiter not provided
start_ptr = line; //Start visiting input. We will distinguish tokens in a single pass, for good performance.
//Then we are allocating one unified memory region & doing one memory copy.
while ( ( end_ptr = strstr( start_ptr, delim ) ) ) {
start_idx[ tokens_found -1 ] = start_ptr - line; //Store the Index of current token
end_idx[ tokens_found - 1 ] = end_ptr - line; //Store Index of first character that will be replaced with
//'\0'. Example: "arg1||arg2||end" -> "arg1\0|arg2\0|end"
tokens_found++; //Accumulate the count of tokens.
start_ptr = end_ptr + delim_size; //Set pointer to the next c-string within the line
}
for ( iter = start_ptr; (*iter!='\0') ; iter++ );
start_idx[ tokens_found -1 ] = start_ptr - line; //Store the Index of current token: of last token here.
end_idx[ tokens_found -1 ] = iter - line; //and the last element that will be replaced with \0
line_size = iter - line; //Saving CPU cycles: Indirectly Count the size of *line without using strlen();
int size_ptr_region = (1 + tokens_found)*sizeof( char* ); //The size to store pointers to c-strings + 1 (*NULL).
out = (char**) malloc( size_ptr_region + ( line_size + 1 ) + 5 ); //Fit everything there...it is all memory.
//It reserves a contiguous space for both (char**) pointers AND string region. 5 Bytes for "Out of Range" tests.
*out_storage = out; //Update the char** pointer of the caller function.
//"Out of Range" TEST. Verify that the extra reserved characters will not be changed. Assign Some Values.
//char *extra_chars = (char*) out + size_ptr_region + ( line_size + 1 );
//extra_chars[0] = 1; extra_chars[1] = 2; extra_chars[2] = 3; extra_chars[3] = 4; extra_chars[4] = 5;
for ( i = 0; i < tokens_found; i++ ) //Assign adresses first part of the allocated memory pointers that point to
out[ i ] = (char*) out + size_ptr_region + start_idx[ i ]; //the second part of the memory, reserved for Data.
out[ tokens_found ] = (char*) NULL; //[ ptr1, ptr2, ... , ptrN, (char*) NULL, ... ]: We just added the (char*) NULL.
//Now assign the Data: c-strings. (\0 terminated strings):
char *str_region = (char*) out + size_ptr_region; //Region inside allocated memory which contains the String Data.
memcpy( str_region, line, line_size ); //Copy input with delimiter characters: They will be replaced with \0.
//Now we should replace: "arg1||arg2||arg3" with "arg1\0|arg2\0|arg3". Don't worry for characters after '\0'
//They are not used in standard c lbraries.
for( i = 0; i < tokens_found; i++) str_region[ end_idx[ i ] ] = '\0';
//"Out of Range" TEST. Wait until Assigned Values are Printed back.
//for ( int i=0; i < 5; i++ ) printf("c=%x ", extra_chars[i] ); printf("\n");
// *out memory should now contain (example data):
//[ ptr1, ptr2,...,ptrN, (char*) NULL, "token1\0", "token2\0",...,"tokenN\0", 5 bytes for tests ]
// |__________________________________^ ^ ^ ^
// |_______________________________________| | |
// |_____________________________________________| These 5 Bytes should be intact.
return tokens_found;
}
int main()
{
char in_line[] = "Arg1;;Th;s is not Del;m;ter;;Arg3;;;;Final";
char delim[] = ";;";
char **columns;
int i;
printf("Example1:\n");
columns = NULL; //Should be NULL to indicate that it is not assigned to allocated memory. Otherwise return -4;
int cols_found = getcols( in_line, delim, &columns);
for ( i = 0; i < cols_found; i++ ) printf("Column[ %d ] = %s\n", i, columns[ i ] ); //<- (1st way).
// (2nd way) // for ( i = 0; columns[ i ]; i++) printf("start_idx[ %d ] = %s\n", i, columns[ i ] );
free( columns ); //Release the Single Contiguous Memory Space.
columns = NULL; //Pointer = NULL to indicate it does not reserve space and that is ready for the next malloc().
printf("\n\nExample2, Nested:\n\n");
char example_file[] = "ID;Day;Month;Year;Telephone;email;Date of registration\n"
"1;Sunday;january;2009;123-124-456;jitter#go.xyz;2015-05-13\n"
"2;Monday;March;2011;(+30)333-22-55;buffer#wl.it;2009-05-23";
char **rows;
int j;
rows = NULL; //getcols() requires it to be NULL. (Avoid dangling pointers, leaks e.t.c).
getcols( example_file, "\n", &rows);
for ( i = 0; rows[ i ]; i++) {
{
printf("Line[ %d ] = %s\n", i, rows[ i ] );
char **columnX = NULL;
getcols( rows[ i ], ";", &columnX);
for ( j = 0; columnX[ j ]; j++) printf(" Col[ %d ] = %s\n", j, columnX[ j ] );
free( columnX );
}
}
free( rows );
rows = NULL;
return 0;
}
A complete example which leaves the fields as NULL-terminated strings in the original input buffer and provides access to them via an array of char pointers. The CSV processor has been confirmed to work with fields enclosed in "double quotes", ignoring any delimiter chars within them.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// adjust BUFFER_SIZE to suit longest line
#define BUFFER_SIZE 1024 * 1024
#define NUM_FIELDS 10
#define MAXERRS 5
#define RET_OK 0
#define RET_FAIL 1
#define FALSE 0
#define TRUE 1
// char* array will point to fields
char *pFields[NUM_FIELDS];
// field offsets into pFields array:
#define LP 0
#define IMIE 1
#define NAZWISKo 2
#define ULICA 3
#define NUMER 4
#define KOD 5
#define MIEJSCOw 6
#define TELEFON 7
#define EMAIL 8
#define DATA_UR 9
long loadFile(FILE *pFile, long *errcount);
static int loadValues(char *line, long lineno);
static char delim;
long loadFile(FILE *pFile, long *errcount){
char sInputBuf [BUFFER_SIZE];
long lineno = 0L;
if(pFile == NULL)
return RET_FAIL;
while (!feof(pFile)) {
// load line into static buffer
if(fgets(sInputBuf, BUFFER_SIZE-1, pFile)==NULL)
break;
// skip first line (headers)
if(++lineno==1)
continue;
// jump over empty lines
if(strlen(sInputBuf)==0)
continue;
// set pFields array pointers to null-terminated string fields in sInputBuf
if(loadValues(sInputBuf,lineno)==RET_FAIL){
(*errcount)++;
if(*errcount > MAXERRS)
break;
} else {
// On return pFields array pointers point to loaded fields ready for load into DB or whatever
// Fields can be accessed via pFields, e.g.
printf("lp=%s, imie=%s, data_ur=%s\n", pFields[LP], pFields[IMIE], pFields[DATA_UR]);
}
}
return lineno;
}
static int loadValues(char *line, long lineno){
if(line == NULL)
return RET_FAIL;
// chop of last char of input if it is a CR or LF (e.g.Windows file loading in Unix env.)
// can be removed if sure fgets has removed both CR and LF from end of line
if(*(line + strlen(line)-1) == '\r' || *(line + strlen(line)-1) == '\n')
*(line + strlen(line)-1) = '\0';
if(*(line + strlen(line)-1) == '\r' || *(line + strlen(line)-1 )== '\n')
*(line + strlen(line)-1) = '\0';
char *cptr = line;
int fld = 0;
int inquote = FALSE;
char ch;
pFields[fld]=cptr;
while((ch=*cptr) != '\0' && fld < NUM_FIELDS){
if(ch == '"') {
if(! inquote)
pFields[fld]=cptr+1;
else {
*cptr = '\0'; // zero out " and jump over it
}
inquote = ! inquote;
} else if(ch == delim && ! inquote){
*cptr = '\0'; // end of field, null terminate it
pFields[++fld]=cptr+1;
}
cptr++;
}
if(fld > NUM_FIELDS-1){
fprintf(stderr, "Expected field count (%d) exceeded on line %ld\n", NUM_FIELDS, lineno);
return RET_FAIL;
} else if (fld < NUM_FIELDS-1){
fprintf(stderr, "Expected field count (%d) not reached on line %ld\n", NUM_FIELDS, lineno);
return RET_FAIL;
}
return RET_OK;
}
int main(int argc, char **argv)
{
FILE *fp;
long errcount = 0L;
long lines = 0L;
if(argc!=3){
printf("Usage: %s csvfilepath delimiter\n", basename(argv[0]));
return (RET_FAIL);
}
if((delim=argv[2][0])=='\0'){
fprintf(stderr,"delimiter must be specified\n");
return (RET_FAIL);
}
fp = fopen(argv[1] , "r");
if(fp == NULL) {
fprintf(stderr,"Error opening file: %d\n",errno);
return(RET_FAIL);
}
lines=loadFile(fp,&errcount);
fclose(fp);
printf("Processed %ld lines, encountered %ld error(s)\n", lines, errcount);
if(errcount>0)
return(RET_FAIL);
return(RET_OK);
}
Use fscanf to read the file until you encounter ';' or \n, then just skip it with fscanf(f, "%*c").
int main()
{
char str[128];
int result;
FILE* f = fopen("test.txt", "r");
/*...*/
do {
result = fscanf(f, "%127[^;\n]", str);
if(result == 0)
{
result = fscanf(f, "%*c");
}
else
{
//Put here whatever you want to do with your value.
printf("%s\n", str);
}
} while(result != EOF);
return 0;
}
This code is fairly simple, but effective. It parses comma-separated files with parenthesis. You can easily modify it to suit your needs.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
// argv[1] path to csv file
// argv[2] number of lines to skip
// argv[3] length of longest value (in characters)
FILE *pfinput;
unsigned int nSkipLines, currentLine, lenLongestValue;
char *pTempValHolder;
int c;
unsigned int vcpm; // Value character marker
int QuotationOnOff; // 0 - off, 1 - on
nSkipLines = atoi(argv[2]);
lenLongestValue = atoi(argv[3]);
pTempValHolder = (char*)malloc(lenLongestValue);
if(pfinput = fopen(argv[1], "r")) {
rewind(pfinput);
currentLine = 1;
vcpm = 0;
QuotationOnOff = 0;
// currentLine > nSkipLines condition
// skips / ignores first argv[2] lines
while((c = fgetc(pfinput)) != EOF)
{
switch(c)
{
case ',':
if(!QuotationOnOff && currentLine > nSkipLines)
{
pTempValHolder[vcpm] = '\0';
printf("%s,", pTempValHolder);
vcpm = 0;
}
break;
case '\n':
if(currentLine > nSkipLines)
{
pTempValHolder[vcpm] = '\0';
printf("%s\n", pTempValHolder);
vcpm = 0;
}
currentLine++;
break;
case '\"':
if(currentLine > nSkipLines)
{
if(!QuotationOnOff) {
QuotationOnOff = 1;
pTempValHolder[vcpm] = c;
vcpm++;
} else {
QuotationOnOff = 0;
pTempValHolder[vcpm] = c;
vcpm++;
}
}
break;
default:
if(currentLine > nSkipLines)
{
pTempValHolder[vcpm] = c;
vcpm++;
}
break;
}
}
fclose(pfinput);
free(pTempValHolder);
}
return 0;
}
#include <conio.h>
#include <stdio.h>
#include <string.h>
// Driver Code
int main()
{
// Substitute the full file path
// for the string file_path
FILE* fp = fopen("Movie.csv", "r");
char *wrds[40];
if (!fp)
printf("Can't open file\n");
else {
// Here we have taken size of
// array 1024 you can modify it
char buffer[1024];
int row = 0;
int column = 0;
while (fgets(buffer, 1024, fp)) {
column = 0;
row++;
// To avoid printing of column
// names in file can be changed
// according to need
if (row == 1)
continue;
// Splitting the data
char* value = strtok(buffer, ", ");
while (value) {
// Column 1
if (column == 0) {
printf("Name :");
}
// Column 2
if (column == 1) {
printf("\tAccount No. :");
}
// Column 3
if (column == 2) {
printf("\tAmount :");
}
printf("%s", value);
wrds[column] = value;
value = strtok(NULL, ", ");
column++;
}
printf("\n");
}
// Close the file
fclose(fp);
}
getchar();
return 0;
}
calculate the sum of squares of given integers, excluding any negatives.
The first line of the input will be an integer N (1 <= N <= 100), indicating the number of test cases to follow.
Each of the test cases will consist of a line with an integer X (0 < X <= 100), followed by another line consisting of X number of space-separated integers Yn (-100 <= Yn <= 100).
For each test case, calculate the sum of squares of the integers, excluding any negatives, and print the calculated sum in the output.
Note: There should be no output until all the input has been received.
Note 2: Do not put blank lines between test cases solutions.
Note 3: Take input from standard input, and output to standard output.
Rules
Write your solution using Go Programming Language
Your source code must be a single file (package main)
Do not use any for statement
You may only use standard library packages
"Problem which I am facing"
'square' function below is not getting executed the required number of times according to the input test cases. To meet specific requirements I wasn't allowed to use the 'for' statement. Please help me out. Language is Go.
package main
import "fmt"
var s []int
func square(l int) {
i := 0
sum := 0
Square:
if l > 0 {
s[i] = s[i] * s[i]
sum = sum + s[i]
i++
l--
goto Square
}
fmt.Println(sum)
}
func myfunc(a int) {
Here:
if a > 0 {
var b int
fmt.Scanln(&b)
if b > 0 {
s = append(s, b)
}
a--
goto Here
}
}
func main() {
var a int
fmt.Scanln(&a)
TestCases:
if a > 0 {
var T int
fmt.Scanln(&T)
myfunc(T)
a--
goto TestCases
}
square(len(s))
}
Here is an implementation using recursion:
package main
import "fmt"
func testCase(N int) {
if N <= 0 {
return
}
var X int
fmt.Scanf("%d", &X)
fmt.Println(sumOfSquare(X))
testCase(N-1)
}
func sumOfSquare(X int) int {
if X == 0 {
return 0
}
var Y int
fmt.Scanf("%d", &Y)
if Y > 0 {
return Y*Y + sumOfSquare(X-1)
}
return sumOfSquare(X-1)
}
func main() {
var N int
fmt.Scanf("%d", &N)
testCase(N)
}
Here is an example output:
$ go run main.go
2 4 3 -1 1 14 5 9 6 -53 32 16
206
1397
I have this program in python using recursion, but not in go-lang.
Here is the code
def squaresum(counter,alist):
if counter==0:
return 0
else:
if int(alist[counter-1])<0:
return 0 + squaresum(counter-1, alist)
else:
return int(alist[counter-1])**2 + squaresum(counter-1,alist)
def testcase(a):
if a==0:
return
terms = int(input())
nums = input()
list1 = nums.split()
print(squaresum(terms,list1))
testcase(a-1)
if __name__=='__main__':
casecount = int(input())
testcase(casecount)
When i want to perform a reduction on an array of float i usually do the following :
float res = *thrust::max_element(thrust::device,
thrust::device_ptr<float>(dDensities),
thrust::device_ptr<float>(dDensities+numParticles)
);
However what i would like to do now is pretty much the same thing on a vec3 (the glm library type) array :
float res = *thrust::max_element(thrust::device,
thrust::device_ptr<glm::vec3>(dDensities),
thrust::device_ptr<glm::vec3>(dDensities+numParticles)
);
As you can see, this has no sense because the '<' operator is not defined on. But i would like to get the maximum vec3 based on his length :
len = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z);
Is that possible ?
Yes, its possible. You may want to read the thrust quickstart guide if you're not already familiar with it.
If you review the thrust extrema documentation, you'll note that thrust::max_element comes in several different varieties (as do most thrust algorithms). One of these accepts a binary comparison functor. We can define a comparison functor which will do what you want.
Here's a trivial worked example:
$ cat t134.cu
#include <thrust/extrema.h>
#include <thrust/device_ptr.h>
#include <glm/glm.hpp>
#include <iostream>
struct comp
{
template <typename T>
__host__ __device__
bool operator()(T &t1, T &t2){
return ((t1.x*t1.x+t1.y*t1.y+t1.z*t1.z) < (t2.x*t2.x+t2.y*t2.y+t2.z*t2.z));
}
};
int main(){
int numParticles = 3;
glm::vec3 d[numParticles];
d[0].x = 0; d[0].y = 0; d[0].z = 0;
d[1].x = 2; d[1].y = 2; d[1].z = 2;
d[2].x = 1; d[2].y = 1; d[2].z = 1;
glm::vec3 *dDensities;
cudaMalloc(&dDensities, numParticles*sizeof(glm::vec3));
cudaMemcpy(dDensities, d, numParticles*sizeof(glm::vec3), cudaMemcpyHostToDevice);
glm::vec3 res = *thrust::max_element(thrust::device,
thrust::device_ptr<glm::vec3>(dDensities),
thrust::device_ptr<glm::vec3>(dDensities+numParticles),
comp()
);
std::cout << "max element x: " << res.x << " y: " << res.y << " z: " << res.z << std::endl;
}
$ nvcc -arch=sm_61 -o t134 t134.cu
$ ./t134
max element x: 2 y: 2 z: 2
$
I have a system of 4 coupled equations to solve and a parameter Gamma[i] to iterate over. Since I am quite new to C++, my code is a very rudimentary. If it looks sophisticated and elegant in certain parts, it is only because I have adapted code from the author of odeint. :)
This question is related to (http://stackoverflow.com/questions/12060111/using-odeint-function-definition/12066958#comment16253600_12066958) but not exactly the same. Please do not delete this. :(
Questions have been inserted between the lines of code.
#include <iostream>
#include <iterator>
#include <algorithm>
#include <boost/numeric/odeint.hpp>
#include <cmath>
#include <vector>
#include <fstream>
#include <iomanip>
using namespace std;
using namespace boost::numeric::odeint;
class NLI_class {
private:
double gamma;
public:
NLI_class (double r) : gamma(r) {}
void operator()( vector<double> &u , vector<double> &du , double z ) {
du[0] = u[0]*u[1]*cos(u[3]); //u1
du[1] = -u[0]*u[0]*cos(u[3]); //u2
du[2] = gamma * (2/(u[0]*u[0]) - 1/(u[1]*u[1])); //theta
du[3] = gamma * (1.0/(u[0]*u[0])); //phi1
du[4] = gamma * (1.0/(u[1]*u[1])); //phi2;
}
};
Question #1:
In my original program, I had something like this to pipe the output to a csv file:
inline void save(vector<double>& v, string filename)
{
ofstream output(filename);
for(int i=0;i<v.size();++i){
output << setprecision(64) << v[i] << endl;
}
}
How do I adapt streaming_observer to do what my save() does? Basically, I want to generate .csv files for each iteration i. At this point, I am doing it the ugly way, i.e compiling everything, opening a windows command prompt and then piping the exe output to a text file. This generates one big file with all iterations thrown in there.
This becomes very painful to analyze for a large number of iterations.
struct streaming_observer {
std::ostream &m_out;
streaming_observer( std::ostream &out ) : m_out( out ) {}
void operator()( const vector<double> &x , double t ) const
{
m_out << t;
for( size_t i=0 ; i < x.size() ; ++i )
m_out << "\t" << x[i];
m_out << "\n";
}
};
int main(){
vector<double> x( 5 );
vector<double> Gamma;
vector<double>delta;
const double pi=acos(-1.0);
short delta_n=5;
const double delta_step=(2*pi)/delta_n;
const double dz = 0.01;
const double zeta = 3.0;
const double theta_initial=0.0;
const double u20=tanh(zeta);
const double u10=sqrt(1.0-(u20*u20));
double d=0.0;
double G=0.0;
for(int i=0;i<=delta_n;i++){
//When i=0, the d=0.0 and G=0.0 are pushed into the vector.
delta.push_back(d);
Gamma.push_back(G);
// Compute delta and Gamma
d=d+delta_step;
G=-u10*u10*u20*sin(theta_initial+d);
}
save(delta,"delta.csv");
save(Gamma,"Gamma.csv");
Question#2:
The results I get here do not agree with what I get with what I get using a simple explicit Euler method. Hence, I would like to see the RK4 coefficients (preferably dump them to a file) or the intermediate steps. How can I get this information?
//Numeric Integration
for (unsigned i = 0; i < Gamma.size(); ++i) {
x[0] = u10;
x[1] = u20;
x[2] = 0.0;
x[3] = 0.0;
x[4] = 0.0;
NLI_class nli_obj(Gamma[i]);
integrate_const( runge_kutta4< vector<double > >(), nli_obj, x , 0.0 , 3.0 , dz,streaming_observer( std::cout ) );
}
}
Thank you for all those who helped!
Edit:
Is there some way to get a running error estimate? Note that u[0]*u[0]+u[1]*u[1]=1 at all times.
Question #1 :
I do not understand exactly what kind of output you need. But if you want to write the result after each iteration you can implement an output observer like this:
struct output_observer
{
string filename_;
size_t count_;
output_observer( const string &filename ) : filename_( filename ) , count_( 0 ) { }
void operator()( const state_type &x , time_type dt )
{
char fn[512] = "";
sprintf( fn , "%s_%04lu.csv" , filename_.c_str() , count_ );
ofstream fout( fn );
for( size_t i=0 ; i<x.size() ; ++i ) fout << x[i] << "\n";
++count_;
}
};
You can apply this observer simply by
integrate_const( runge_kutta4< vector<double > >() , nli_obj , x ,
0.0 , 3.0 , dz , output_observer( "filename" ) );
Is this the desired functionality?
Question #2 :
It is not possible to see the intermediate e steps of runge_kutta4. The coefficients are the standard ones for the classical Runge-Kutta method: http://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods
Question #3 :
odeint has several error steppers, which estimate the error made during one step. You can use for example the Runge_Kutta Cash Karp algorithm;
runge_kutta_cash_karp54< state_type > rk;
state_type xerr;
rk.do_step( nli_obj , x , t , xerr );
which makes ONE step and estimates the error and writes the error result in xerr.
I'm currently working with CUSPARSE. I'm having trouble because I don't know how to print a complex number. For example, when I write:
cuComplex a;
a.x=1.2;
a.y=2.2;
How do I print the varable a?
I've tried :
cout<< a;
but it doesn't work.
You will need to overload the << operator to take in cuComplex and cuDoubleComplex data types.
std::ostream& operator<<(std::ostream& strm, const cuComplex& in)
{
char sgn[2] = "+-"
strm << in.x << sgn[in.y < 0] << " i"<< std::abs(in.y);
return strm;
}
You can do the same for cuDoubleComplex
The data in std::complex is identical to the corresponding data in a cuComplex, i.e. you can reinterpret_cast pointers (and therefore arrays, too) of one type to the other – it works in practise and is, I think, actually guaranteed by C++11, you can test it like this:
namespace check_stdComplexdouble_to_cuDoubleComplex_binary_compatibility{
using std::complex;
const complex<double> testarr[] = { complex<double>(0.,.5)
, complex<double>(1.,1.5) };
const cuDoubleComplex* cucomplexd
= reinterpret_cast<const cuDoubleComplex*>(testarr);
auto tester() -> bool {
assert( cuCreal(cucomplexd[0])==0. && cuCimag(cucomplexd[0])==.5
&& cuCreal(cucomplexd[1])==1. && cuCimag(cucomplexd[1])==1.5 );
return true;
}
const bool ok = tester();
bool good(){return ok;}
};
If you call a CUBLAS function that's supposed to read/write from/to an std::complex<float>, you can just give it a reinterpret_casted pointer, e.g.
std::complex<double> result;
xhandle->cublasstat = yhandle->cublasstat
= cublasZdotc( *xhandle->cublashandle
, xhandle->vect_dimension
, xhandle->vector, 1
, yhandle->vector, 1
, reinterpret_cast<cuDoubleComplex*>(&result) );