我希望标题中的问题的答案是我做了一些愚蠢的事情!
这是问题所在.我想计算一个真实对称矩阵的所有特征值和特征向量.我已经使用GNU Scientific Library在MATLAB中实现了代码(实际上,我使用Octave运行它)和C++ .我在下面提供了完整的代码用于两种实现.
据我所知,GSL带有自己的BLAS API实现,(以下我将其称为GSLCBLAS)并使用我使用以下编译的库:
g++ -O3 -lgsl -lgslcblas
Run Code Online (Sandbox Code Playgroud)
GSL表明这里使用替代BLAS库,如自我优化ATLAS库,以提高性能.我正在运行Ubuntu 12.04,并已从Ubuntu存储库安装了ATLAS软件包.在这种情况下,我编译使用:
g++ -O3 -lgsl -lcblas -latlas -lm
Run Code Online (Sandbox Code Playgroud)
对于所有三种情况,我已经使用随机生成的大小为100到1000的矩阵进行了实验,步长为100.对于每个大小,我执行10个具有不同矩阵的特征分解,并平均所花费的时间.结果如下:

性能上的差异是荒谬的.对于大小为1000的矩阵,Octave在一秒钟内执行分解; GSLCBLAS和ATLAS大约需要25秒.
我怀疑我可能错误地使用了ATLAS库.欢迎任何解释; 提前致谢.
关于代码的一些注意事项:
在C++实现中,不需要使矩阵对称,因为该函数仅使用它的下三角部分.
在Octave中,该行triu(A) + triu(A, 1)'强制矩阵是对称的.
如果您希望将C++代码编译为您自己的Linux机器,则还需要添加该标志-lrt,因为该clock_gettime功能.
不幸的是我不认为clock_gettime退出其他平台.考虑将其更改为gettimeofday.
八度代码
K = 10;
fileID = fopen('octave_out.txt','w');
for N = 100:100:1000
AverageTime = 0.0;
for k = 1:K
A = randn(N, N);
A = triu(A) + triu(A, 1)'; …Run Code Online (Sandbox Code Playgroud) 我已经做了几年的控制台编程,现在是时候了解一下GUI的迷人世界.我在wxWidgets中涉猎过一点点; 编写了一个Hello World程序,稍微玩了一下,等等.
现在我是那些有"低级诅咒"的人之一:我不知道如何使用有效的东西 - 我想知道引擎盖下发生了什么,即使它很少或者没有实际价值.
所以我一直在阅读这个主题(例如这里),但我发现很难绕过所有不同的系统,工具包和他们做的事情.到目前为止,我已经发现了(如果我错了,请纠正我):
现在提出一些问题:坚持使用类UNIX系统:
对于奖金,也许是Windows操作系统呢?它是否遵循类似的结构,还是完全按照自己的方式进行?
首先,我指定A为结构和其他两个结构:B具有相同的元素顺序,并C具有不同的元素顺序.
A.x = 11;
A.y = 11;
B.x = 21;
B.y = 22;
C.y = 31; %// Note that I am specifying
C.x = 32; %// y first and x second
A = B; %// Works fine
A = C; %// Works fine
Run Code Online (Sandbox Code Playgroud)
分配A给B和C工作,这是我对结构的期望 - 元素的顺序无关紧要.
现在,我指定A为结构数组,而不是一个结构,并试图转让其要素之一B,并C分别为:
clear;
A(1).x = 11;
A(1).y = 12;
B.x = 21;
B.y = 22;
C.y = …Run Code Online (Sandbox Code Playgroud) 对不起,如果这是一个重复的问题,但我一直在寻找几个小时,而且我得到了相互矛盾的答案......更糟糕的是,他们都没有工作.
这很简单.我有很多源文件,我有一些常见的参数,我想在一个文件中,比如"Parameters.h".我想在运行时设置这些参数(一次),方法是将它们作为参数传递给程序.
PS:我知道更好的方法是将所有内容作为参数传递给函数,但它是一块很大的代码,我需要尽快得到一个结果,而不需要做太多的更改.
这是一个最小的工作示例:
Parameters.h
#ifndef PARAMETERS_H_
#define PARAMETERS_H_
extern int Alpha;
#endif
Run Code Online (Sandbox Code Playgroud)
main.cpp中
#include <iostream>
#include "Parameters.h"
int main(int argc, char * argv[])
{
const int Alpha = 12.0;
}
Run Code Online (Sandbox Code Playgroud)
Functions.cpp
#include "Parameters.h"
double Foo(const double& x)
{
return Alpha*x;
}
Run Code Online (Sandbox Code Playgroud)
当我编译时
gcc main.cpp Functions.cpp
Run Code Online (Sandbox Code Playgroud)
我收到错误"Functions.cpp :(.text + 0xa):未定义引用"Alpha"".
我是一个不错的程序程序员,但我是一个面向对象的新手(我是一个好老帕斯卡和C的工程师.)我觉得特别棘手的是选择其中一种方法来实现同样的目的.对于C++来说尤其如此,因为它的强大功能可以让你做任何你喜欢的事情,甚至可怕的事情(我想这里的权力/责任格言是合适的).
我认为这可能有助于我运行一个我正在与社区斗争的特定案例,以了解人们如何做出这些选择.我正在寻找的是与我的具体案例相关的建议,以及更一般的指针(没有双关语意).开始:
作为练习,我正在开发一个简单的模拟器,其中"几何表示"可以有两种类型:"圆"或"多边形".然后,模拟器的其他部分需要接受这些表示,并可能以不同方式处理它们.我已经提出了至少四种不同的方法来做到这一点.每个的优点/缺点/权衡取舍是什么?
答:功能重载
声明Circle和Polygon作为不相关的类,然后重载需要几何表示的每个外部方法.
B:铸造
宣布一个enum GeometricRepresentationType {Circle, Polygon}.声明一个抽象GeometricRepresentation类和继承Circle,并Polygon从它.GeometricRepresentation有一个GetType()由Circle和实现的虚方法Polygon.然后使用方法GetType()和switch语句将a GeometricRepresentation转换为适当的类型.
C:不确定合适的名字
声明枚举类型和抽象类,如B中所示.在这个类中,还创建函数Circle* ToCircle() {return NULL;}和Polygon* ToPolygon() {return NULL;}.然后每个派生类重载相应的函数,返回this.这仅仅是动态铸造的重新发明吗?
D:一起束缚他们
将它们实现为具有枚举成员的单个类,该成员指示对象的类型.该类具有可以存储两种表示的成员.然后由外部方法决定不要调用愚蠢的函数(例如GetRadius()在多边形或GetOrder()圆上).
我对OOP比较新.有时我遇到的情况是我不确定方法应该去哪里.我会尝试给出一个最小的例子; 我希望我不要过分夸大它.
假设我有一个Point持有点位置的Line类,以及一个包含直线方程的类.我现在需要一种计算a Point和a 之间(垂直)距离的方法Line.我可以:
在OOP中是否有一种首选方式,还是依赖于语言?在C++中,一个独立的函数是一个选项,但是由于我对Java的有限理解,它不允许独立的函数.在那种情况下你会创建一个类PointLineDistanceCalculator吗?
virtualC ++ 的主要优点之一是能够使用基类(指针或引用)来调用派生方法。
我正在阅读使用CRTP实现静态多态性的知识,但是我不明白如何使用该技术实现上面提到的内容,因为Base当需要模板时,我无法将函数声明为采用类型。
在我看来,仅通过使用函数重载就可以实现本文中描述的内容,因此,我敢肯定,该技术必须有更多的功能。
(PS:在回答该问题的评论中提到了这个确切的问题,但不幸的是没有人回答:“ vtables真正提供的功能是使用基类(指针或引用)来调用派生方法。您应该在此处显示如何使用CRTP进行操作。”)
这是我的最小代码,它给出错误“在'&'令牌无效Print(Base&Object)之前缺少模板参数”。
#include <cstring>
#include <iostream>
template <typename Derived>
struct Base
{
std::string ToStringInterface() { return static_cast<Derived*>(this)->ToString(); }
std::string ToString() { return "This is Base."; }
};
struct Derived : Base<Derived>
{
std::string ToString() { return "This is Derived."; }
};
void Print(Base& Object)
{
std::cout << Object->ToStringInterface() << std::endl;
}
int main()
{
Derived MyDerived;
// This works, but could have been achieved with a function …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用C++自定义文字.我发现奇怪的是,当我将类型从long double类型更改为double或者尝试通过引用传递时,下面的简单函数停止工作.
起初我认为它与使用有关,constexpr但似乎并非如此,因为如果它们不在,这两种工作都很好operator "",并且constexpr从中operator ""删除不会删除错误.
这些经过深思熟虑的决策是在语言设计中,还是仅仅是我的编译器(gcc 4.8.2)无法处理的细微差别?
// Conversion function, works fine with both long double and
// double, and with or without pass by reference.
constexpr long double to_deg (const long double& deg)
{
return deg*M_PI/180.0;
}
// Custom literal with long double types and pass by value,
// works fine.
constexpr long double operator "" _deg (long double deg)
{
return deg*M_PI/180.0;
}
// Custom literal …Run Code Online (Sandbox Code Playgroud) 我知道使用const_cast通常是坏主意,但我正在玩它,我遇到了一个奇怪的行为,其中:
两个指针具有相同的地址值,但在取消引用时,给出不同的数据值.
有没有人对此有解释?
码
#include <iostream>
int main()
{
const int M = 10;
int* MPtr = const_cast<int*>(&M);
(*MPtr)++;
std::cout << "MPtr = " << MPtr << " (*MPtr) = " << (*MPtr) << std::endl;
std::cout << " &M = " << &M << " M = " << M << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
产量
MPtr = 0x7fff9b4b6ce0 (*MPtr) = 11
&M = 0x7fff9b4b6ce0 M = 10
Run Code Online (Sandbox Code Playgroud) 给定两个向量X和Y长度n,表示平面上的点和邻域半径rad,是否有一种矢量化方法来计算点的邻域矩阵?
换句话说,可以对以下(对于大的痛苦缓慢n)循环进行矢量化:
neighborhood_mat = zeros(n, n);
for i = 1 : n
for j = 1 : i - 1
dist = norm([X(j) - X(i), Y(j) - Y(i)]);
if (dist < radius)
neighborhood_mat(i, j) = 1;
neighborhood_mat(j, i) = 1;
end
end
end
Run Code Online (Sandbox Code Playgroud) 这个答案声称const自动指针的行为与const'regular'(即非自动)指针的行为相同,这正是我所期望的.
但是,以下代码编译和输出100:
int n{ 99 };
const auto nPtr = &n;
++(*nPtr);
std::cout << n << '\n';
Run Code Online (Sandbox Code Playgroud)
为了深入挖掘,我检查了所有4种指针的类型,这是我得到的结果:
码
int n{ 99 };
int* intPtr = &n;
const int* intConstPtr = &n;
auto autoPtr = &n;
const auto autoConstPtr = &n;
std::cout << "intPtr: " << typeid(intPtr).name() << '\n';
std::cout << "intConstPtr: " << typeid(intConstPtr).name() << '\n';
std::cout << "autoPtr: " << typeid(autoPtr).name() << '\n';
std::cout << "autoConstPtr: " << typeid(autoConstPtr).name() << '\n';
Run Code Online (Sandbox Code Playgroud)
产量
intPtr:int*__ptr64
intConstPtr:int const*__ptr64 …