Operating on slices of Cube in armadillo - c++

I am trying to get used to armadillo linear algebra library for c++ and I cannot figure out hot to operate on slices(matrices) of a cube. Whenever I try to operate on a slice, the program compiles but does not give any output, not even the outputs of statement before the slice operation.
Here's the code:
#include <armadillo>
#include <iostream>
using namespace arma;
using namespace std;
int main()
{
Cube<double> A(3 , 5 ,1, fill::randu);
Cube<double>B(5,3,1,fill::randu);
Mat<double>x =A.slice(0);
Mat<double>y = B.slice(0);
cout << x << "\n" << y << endl;
cout << x*y << endl; //code works fine if this line is removed
}
the problem is that the code works fine if the last line is removed. Why does this happen? Is there a better way to operate on matrices inside a cube ?

Use directions given in the accepted answer to this question, to install Armadillo on Windows using Visual Studio.
If you have asked the Linker to use blas_win64_MT.lib and lapack_win64_MT.lib libraries, make sure to add the respective .dll's in the same directory as your .exe file. Then using this code, I get the desired output.
#include <armadillo>
#include <iostream>
using namespace std;
using namespace arma;
int main()
{
Cube<double> A(3, 5, 1, fill::randu);
Cube<double> B(5, 3, 1, fill::randu);
Mat<double> x = A.slice(0);
Mat<double> y = B.slice(0);
std::cout << "x:\n" << x << "\ny:\n" << y << std::endl;
std::cout << "x*y:\n" << x*y << std::endl;
}
Output in command window:
Hope that helps!

Related

I included StlLock.h in my .h file and got these errors

Ok, so I just installed Visual Studio yesterday and was just minding my own business trying to make a learn C++/wasting time. I ran the code you're about to see a few times without issue and then I included the StlLock.h file, then I happened upon this error list.
Error list in my Visual Studio along with the "problematic" code, I guess.
The errors vanish as soon as I remove StlLock.h.
As far as I recall I did not touch StlLock.h at all. Is there just something wrong with it?
Also, I'm pretty new to programming and C++. I'm trying to teach myself but got caught up in this.
The full code is in 2 files:
ABLASAN.cpp
#include "ABLASAN.h"
int main()
{
Math test;
test.Show_Atributes();
test.radijus = 4;
std::cout << test.Area(test.radijus) << "\n";
std::cin.get();
}
ABLASAN.h
#pragma once
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <StlLock.h>
#include <cmath>
constexpr double PI = 3.14159265358979323846;
class Math{
public:
double radijus, x_os, y_os;
Math(){
x_os = 0;
y_os = 0;
radijus = 0;
}
double Area(double x, double y)
{
return x * y;
}
double Area(double r)
{
return pow(r, 2) * PI;
}
void Show_Atributes() {
std::cout << "X-os: " << x_os << "\nY-os: " << y_os << "\nRadijus: " << radijus << std::endl;
}
};
P.S.
Just as a side-note: I used the cmath file and read somewhere that that file has defined mathematical constants using this:
#define _USE_MATH_DEFINES
#include <cmath>
#include <iostream>
int main() {
std::cout << M_PI << " " << M_E << " " << M_SQRT2 << endl;
return 0;
}
I can't seem to get that to work.
I'm using the Visual Studio C++20 compiler just in case it's important. Also, I did not change any project settings/properties/anything.
Thanks to everyone and anyone in advance.
Also, I'm deeply sorry if this was already answered somewhere. I just didn't find it before writing this up.

CGAL::Voronoi_diagram_2 rounding to integers incorrectly

I am attempting to create a Voronoi diagram from line segments with the following code.
#include <iostream>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Segment_Delaunay_graph_Linf_filtered_traits_2.h>
#include <CGAL/Segment_Delaunay_graph_Linf_2.h>
#include <CGAL/Voronoi_diagram_2.h>
#include <CGAL/Segment_Delaunay_graph_adaptation_traits_2.h>
#include <CGAL/Segment_Delaunay_graph_adaptation_policies_2.h>
using Traits=CGAL::Segment_Delaunay_graph_Linf_filtered_traits_2<CGAL::Exact_predicates_inexact_constructions_kernel>;
using DelaunayGraph=CGAL::Segment_Delaunay_graph_Linf_2<Traits>;
using AdaptationTraits=CGAL::Segment_Delaunay_graph_adaptation_traits_2<DelaunayGraph>;
using AdaptationPolicy=CGAL::Segment_Delaunay_graph_degeneracy_removal_policy_2<DelaunayGraph>;
using VoronoiDiagram=CGAL::Voronoi_diagram_2<DelaunayGraph,AdaptationTraits,AdaptationPolicy>;
using VoronoiSite=AdaptationTraits::Site_2;
using VoronoiPoint=VoronoiSite::Point_2;
int main(int argc, char** argv)
{
VoronoiDiagram vd;
VoronoiPoint pt0(0.0, 0.0), pt1(5.0, 0.0), pt2(2.0, 2.0), pt3(4.0, 4.0);
vd.insert(VoronoiSite::construct_site_2(pt0, pt1));
vd.insert(VoronoiSite::construct_site_2(pt2, pt3));
int c = 0;
for (auto it = vd.edges_begin(); it != vd.edges_end(); it++)
{
std::cout << "Edge #" << c++ << std::endl;
if (it->has_source())
std::cout << "\t" << it->source()->point();
else
std::cout << "\tInfinity";
std::cout << std::endl;
if (it->has_target())
std::cout << "\t" << it->target()->point();
else
std::cout << "\tInfinity";
std::cout << std::endl;
}
return 0;
}
The output starts with
Edge #0
0 2
Infinity
Edge #1
6 2
Infinity
Edge #2
5 1.66667
Infinity
...
This is my custom visualization of what it looks like.
I expect Edge #1 to be the edge that is equidistant to (4, 4) and (5, 0), however the point (6, 2) is NOT equidistant to those two points. I expect that point to be roughly (5.7, 2.3).
Based on edge 2, I know that ALL the numbers are not integers, but it seems like some of them are being rounded or something. To be clear, I very likely lack some very basic CGAL/Kernel knowledge. I tried swapping in the Cartesian<double> kernel, but that did not change the result.
To follow up on Marc's comment, I needed to change the definitions at the top. The result that works is
#include <iostream>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Segment_Delaunay_graph_filtered_traits_2.h>
#include <CGAL/Segment_Delaunay_graph_2.h>
#include <CGAL/Voronoi_diagram_2.h>
#include <CGAL/Segment_Delaunay_graph_adaptation_traits_2.h>
#include <CGAL/Segment_Delaunay_graph_adaptation_policies_2.h>
using CartesianKernel=CGAL::Simple_cartesian<double>;
using Traits=CGAL::Segment_Delaunay_graph_filtered_traits_2<CartesianKernel,CGAL::Field_with_sqrt_tag>;
using DelaunayGraph=CGAL::Segment_Delaunay_graph_2<Traits>;
using AdaptationTraits=CGAL::Segment_Delaunay_graph_adaptation_traits_2<DelaunayGraph>;
using AdaptationPolicy=CGAL::Segment_Delaunay_graph_degeneracy_removal_policy_2<DelaunayGraph>;
using VoronoiDiagram=CGAL::Voronoi_diagram_2<DelaunayGraph,AdaptationTraits,AdaptationPolicy>;
using VoronoiSite=AdaptationTraits::Site_2;
using VoronoiPoint=VoronoiSite::Point_2;

Shifting Letters in Console C++

I am trying to shift the cout text from the console down by moving the console cursor back to the start and outputting '\n'. But when I attempt to nothing happens.
#include <windows.h>
#include <iostream>
using namespace std;
int main() {
cout << "Hello!\nThis is a test!" << endl;
SetConsoleCursorPostion(GetStdHandle(STD_OUTPUT_HANDLE), {0, 0});
cout << '\n';
return 0;
}
Is there anyway to move the text down?
The secondary argument of the SetConsoleCursorPostion is the a coordinate for the cursor, so you have to set it like this: SetConsoleCursorPostion(GetStdHandle(STD_OUTPUT_HANDLE), {0, 2});
And by the way, your code does not compile (#includes ???, no namespace for cout, etc.)
First thing first, Please edit your code to correct typos.
second : (0,0) puts the cursor at the beginning not at bottom.
third: cout should be after SetConsoleCursorPosition.
Last : It is recommended to know the console window dimensions or use other functions to get it.
If you want something facilitates console operations for you as a long term solution check ncurses.
I tested with the following code and it works perfect.
#include <windows.h>
#include <iostream>
using namespace std;
int main() {
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), {5, 5});
cout << "Hello!" << endl;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), {5, 8});
cout << "This is a test!" << endl;
cout << '\n';
return 0;
}

How to compare if two tensors are equal in Eigen?

There is this:
https://codeyarns.com/2016/02/16/how-to-compare-eigen-matrices-for-equality/
But there is no isApprox for tensors.
The following doesn't do what I want:
#include <Eigen/Core>
#include <unsupported/Eigen/CXX11/Tensor>
#include <array>
#include <iostream>
using namespace Eigen;
using namespace std;
int main()
{
// Create 2 matrices using tensors of rank 2
Eigen::Tensor<int, 2> a(2, 3);
Eigen::Tensor<int, 2>* b = &a;
cerr<<(*b==*b)<<endl;
}
because it does coordinate wise comparison and returns a tensor of the same dimension instead of a true/false vale.
How do I check if two tensors are identical? No isApprox for tensors.
I could write my own function, but I want to be able to use GPU power when available, and it seems like Eigen has built-in GPU support.
For an exact comparison of 2 tensors A and B, you can use the comparison operator followed by a boolean reduction:
Tensor<bool, 0> eq = (A==B).all();
This will return a tensor of rank 0 (i.e. a scalar) that contains a boolean value that's true iff each coefficient of A is equal to the corresponding coefficient of B.
There is no approximate comparison at the moment, although it wouldn't be difficult to add.
You can always use a couple of Eigen::Maps to do the isApprox checks.
#include <iostream>
#include <unsupported/Eigen/CXX11/Tensor>
using namespace Eigen;
int main()
{
Tensor<double, 3> t(2, 3, 4);
Tensor<double, 3> r(2, 3, 4);
t.setConstant(2.1);
r.setConstant(2.1);
t(1, 2, 3) = 2.2;
std::cout << "Size: " << r.size() << "\n";
std::cout << "t: " << t << "\n";
std::cout << "r: " << r << "\n";
Map<VectorXd> mt(t.data(), t.size());
Map<VectorXd> mr(r.data(), r.size());
std::cout << "Default isApprox: " << mt.isApprox(mr) << "\n";
std::cout << "Coarse isApprox: " << mt.isApprox(mr, 0.11) << "\n";
return 0;
}
P.S./N.B. Regarding Eigen's built in GPU support... Last I checked it is fairly limited and with good reason. It is/was limited to fixed size matrices as dynamic allocation on a GPU is really something you want to avoid like the common cold (if not like the plague). I take it back. It looks like the Tensor module supports GPUs pretty well.

computing lpNorm column wise in Eigen

When I try to call lpNorm<1> with colwise() in Eigen I get the error:
error: 'Eigen::DenseBase > >::ColwiseReturnType' has no member named 'lpNorm'
Instead norm() and squaredNorm() work fine calling them colwise.
example
#include <Eigen/Dense>
#include <iostream>
using namespace std;
using namespace Eigen;
int main()
{
MatrixXf m(2,2), n(2,2);
m << 1,-2,
-3,4;
cout << "m.colwise().squaredNorm() = " << m.colwise().squaredNorm() << endl;
cout << "m.lpNorm<1>() = " << m.lpNorm<1>() << endl;
// cout << "m.colwise().lpNorm<1>() = " << m.colwise().lpNorm<1>() << endl;
}
works fine giving
m.colwise().squaredNorm() = 10 20
m.lpNorm<1>() = 10
If I uncomment the last line I get the error.
Can someone help?
It is not implemented for colwise in Eigen <=3.2.9. You have two options:
Upgrade to Eigen 3.3 (beta)
Loop over all columns and calculate the lp norms one by one.
You may by-pass it that way:
m.cwiseAbs().colwise().sum()
Unfortunately it only works in case of L1 norm (which is equivalent of an absolute value).