Multiplication - Matrix by imaginary unit - eigen

I would like to ask if anybody knows why this is not working:
For example, let
SparseMatrix<int> A
and
SparseMatrix<std::complex<float> > B
I would like to do the following math:
B=i*A
As code:
std::complex<float> c;
c=1.0i;
B=A.cast<std::complex<float> >()*c;
or equivalent:
B=A.cast<std::complex<float> >()*1.0i;
I expect all real values of A to be imaginary in B but
there are only zeros as (0,0).
Example:
#include <Eigen/Sparse>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace Eigen;
using std::cout;
using std::endl;
int main(int argc, char *argv[]){
int rows=5, cols=5;
SparseMatrix<int> A(rows,cols);
A.setIdentity();
SparseMatrix<std::complex<float> > B;
std::complex<float> c;
c=1i;
B=A.cast<std::complex<float> >()*1.0i;
//B=A.cast<std::complex<float> >()*c;
cout << B << endl;
return 0;
}
compile with:
g++ [name].cpp -o [name]
What am I doing wrong?
Thanks a lot for any help!

You need to enable c++14 to get 1.0i working as expected. With GCC or clang, you need to add the -std=c++14 compiler option.
Then, you can simply do:
MatrixXd A = MatrixXd::Random(3,3);
MatrixXcd B;
B = A * 1.0i;
Same with a SparseMatrix.

Related

Boost::spirit::qi - How do I build a parse rule that sets a property?

I'd like to build a rule that takes in a few parameters from a parsed line then sets a few as constant. Is that possible? An (invalid) example to illustrate what I'm trying to do is below. I think I'm using _r1 incorrectly here, but I'm not sure how to get at the right thing. Assume I don't want to just modify r before sending it into the parser.
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_plus.hpp>
#include <boost/spirit/include/qi_sequence.hpp>
#include <boost/spirit/include/qi_string.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/phoenix/bind/bind_function.hpp>
#include <string>
using namespace boost::spirit::qi;
struct Sample
{
int a;
int b;
};
BOOST_FUSION_ADAPT_STRUCT(Sample, a , b)
const rule<std::string::const_iterator, Sample()> AnythingAndOne = int_ >> eps[_r1.b = 1] >> eoi;
int main()
{
std::string z("3");
Sample r;
parse(z.begin(), z.end(), AnythingAndOne, r);
return 0;
}
Again, with reference to Boost Spirit: "Semantic actions are evil"? I'd avoid the semantic action.
You can directly synthesize a particular attribute value by using qi::attr:
Live On Coliru
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>
struct Sample {
int a;
int b;
};
BOOST_FUSION_ADAPT_STRUCT(Sample, a , b)
namespace qi = boost::spirit::qi;
int main()
{
std::string const z("3");
Sample r;
qi::rule<std::string::const_iterator, Sample()> AnythingAndOne
= qi::int_ >> qi::attr(1) >> qi::eoi;
if (parse(z.begin(), z.end(), AnythingAndOne, r))
std::cout << "Parsed: " << boost::fusion::as_vector(r) << "\n";
else
std::cout << "Parse failed\n";
}
Prints
Parsed: (3 1)

Eigen boolean matrix plus

I would like to do the boolean matrix plus. How could I do it in Eigen?
My following example only gives a scalar +.
#include "Eigen/Dense"
#include <iostream>
using namespace std;
using namespace Eigen;
int main()
{
Eigen::Matrix<bool, 4, 4> m;
m << 0,1,1,1,
1,0,1,0,
1,1,0,0,
1,1,1,0;
cout << m + m; //should be logical_and here
}
How could I use the logical_and here?
Eigen does not seem to provide specific functions to work on boolean matrices. However you can use the fact that booleans are converted to 0 (false) and 1 (true) reliably (see bool to int conversion). Noting that 0=0*0=0*1=1*0 and 1*1=1 it is obvious that multiplication of the booleans as integers is the same (up to type) as logical and. Therefore the following should work:
#include "Eigen/Dense"
#include <iostream>
using namespace std;
using namespace Eigen;
int main()
{
Eigen::Matrix<bool, 4, 4> m;
m << 0,1,1,1,
1,0,1,0,
1,1,0,0,
1,1,1,0;
Eigen::Matrix<bool, 4, 4> result = m.cwiseProduct(m);
cout << result;
}

Why is C++ so much faster than C in this code?

My C code is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void){
char* a = (char*)malloc(200000);
for (int i = 0;i< 100000;i++){
strcat(a,"b");
}
printf("%s",a);
}
My C++ code is
#include <iostream>
int main(void){
std::string a = "";
for (int i = 0;i< 100000;i++){
¦ a+="b";
}
std::cout<<a;
}
On my machine, the C code runs in about 5 seconds, while on my machine, the C++ code runs in 0.025! seconds.
Now, the C code doesn't check for overflows, has no C++ overhead, classes and yet is quite a few magnitudes slower than my C++ code.
Using gcc/g++ 6.2.0 compiled with -O3 on Raspberry Pi.
#erwin was correct.
When I change my code to
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void mystrcat(char* src,char* dest,int lenSrc){
src[lenSrc]=dest[0];
}
int main(void){
char* a = (char*)malloc(200000);
for (int i = 0;i< 100000;i++){
mystrcat(a,"b",i);
}
a[100000] = 0;
printf("%s\n",a);
}
It takes about .012s to run (mostly printing the large screen).
Shlemiel's the painter's algorithm at work!

How to use copy_to_user

I'm trying to add a custom system call into the linux kernel. Here is a simple code:
#include <linux/mysyscall.h>
#include <linux/kernel.h>
#include <asm/uaccess.h>
#include <asm/system.h>
asmlinkage int sys_mysyscall(int *data){
int a = 3;
cli();
copy_to_user(data, &a, 1);
sti();
printk(KERN_EMERG "Called with %d\n", a);
return a;
}
I can compile a kernel with mysyscall added and when I try to access it with a user program like:
#include <linux/mysyscall.h>
int main(void){
int *data;
int r;
int a = 0;
data = &a;
r = mysyscall(data);
printf("r is %d and data is %d", r, *data);
}
*data does not equal to 3 it equals to 0.
How should I use copy_to_user to fix it?
The copy to user line of code copies only one byte from 'a'. In case of little endian systems it is going to be 0. Copy all the 4 bytes to get the correct result.

C++11 sscanf Alternative

I need support for space, tab, and newline delimiters. I can do this with sscanf but I'd prefer to stick to strings rather than char*s.
Is there a way I can acomplish this in C++11?
How about this simple program:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>
int main()
{
std::vector<std::string> v;
std::istringstream is{"example input\ttext\nhere"};
std::copy(std::istream_iterator<std::string>(is),
std::istream_iterator<std::string>(),
std::back_inserter(v));
for (const auto& s : v)
std::cout << s << '\n';
}
The output from this program is
example
input
text
here
As you can see it uses any whitespace as delimiter. You can of course use the input operator as well, like in
std::string s;
while (is >> s)
v.push_back(s);
The above instead of std::copy will produce the same result.

Resources