我想知道用scipy.sparse迭代稀疏矩阵的非零项最好的方法是什么.例如,如果我执行以下操作:
from scipy.sparse import lil_matrix
x = lil_matrix( (20,1) )
x[13,0] = 1
x[15,0] = 2
c = 0
for i in x:
print c, i
c = c+1
Run Code Online (Sandbox Code Playgroud)
输出是
0
1
2
3
4
5
6
7
8
9
10
11
12
13 (0, 0) 1.0
14
15 (0, 0) 2.0
16
17
18
19
Run Code Online (Sandbox Code Playgroud)
因此看起来迭代器正在触及每个元素,而不仅仅是非零条目.我已经看过API了
http://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.lil_matrix.html
并搜索了一下,但我似乎无法找到一个有效的解决方案.
假设我有一个来自scipy.sparse的NxN矩阵M(lil_matrix或csr_matrix),我想让它(N + 1)xN,其中M_modified [i,j] = M [i,j]为0 <= i <N (和所有j)和所有j的M [N,j] = 0.基本上,我想在M的底部添加一行零并保留矩阵的其余部分.有没有办法在不复制数据的情况下执行此操作?
我正在尝试编写一个相当简单的线程应用程序,但它是boost的线程库的新手.我正在研究的一个简单的测试程序是:
#include <iostream>
#include <boost/thread.hpp>
int result = 0;
boost::mutex result_mutex;
boost::thread_group g;
void threaded_function(int i)
{
for(; i < 100000; ++i) {}
{
boost::mutex::scoped_lock lock(result_mutex);
result += i;
}
}
int main(int argc, char* argv[])
{
using namespace std;
// launch three threads
boost::thread t1(threaded_function, 10);
boost::thread t2(threaded_function, 10);
boost::thread t3(threaded_function, 10);
g.add_thread(&t1);
g.add_thread(&t2);
g.add_thread(&t3);
// wait for them
g.join_all();
cout << result << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是,当我编译并运行该程序时,我得到了一个输出
$ ./test
300000
test: pthread_mutex_lock.c:87: __pthread_mutex_lock: Assertion `mutex->__data.__owner == 0' …
Run Code Online (Sandbox Code Playgroud) 似乎可以使用以下代码从特定的Normal分布中生成随机数:
float mean = 0, variance = 1;
boost::mt19937 randgen(static_cast<unsigned int>(std::time(0)));
boost::normal_distribution<float> noise(mean, variance);
variate_generator<mt19937, normal_distribution<float> > nD(randgen, noise);
float random = nD();
Run Code Online (Sandbox Code Playgroud)
这工作正常,但是,我希望能够从几个发行版中绘制数字,即人们会想到如下:
float mean1 = 0, variance1 = 1, mean2 = 10, variance2 = 0.25;
boost::mt19937 randgen(static_cast<unsigned int>(std::time(0)));
boost::normal_distribution<float> noise1(mean1, variance1);
boost::normal_distribution<float> noise2(mean2, variance2);
variate_generator<mt19937, normal_distribution<float> > nD(randgen, noise1);
variate_generator<mt19937, normal_distribution<float> > nC(randgen, noise2);
float random1 = nD();
float random2 = nC();
Run Code Online (Sandbox Code Playgroud)
然而,问题似乎是nD()和nC()正在生成相似的数字序列.我假设这是因为variate_generator的构造函数似乎制作了randgen的副本,而不是显式使用它.因此,生成相同的伪随机序列并简单地推送通过不同的变换(由于分布的不同参数).
有没有人知道在Boost中是否有办法创建一个随机数生成器并将其用于多个发行版?或者,Boost随机库的设计是否打算用户为每个分布创建一个随机数生成器?显然,我可以编写代码将一系列均匀随机数转换为来自任意分布的序列,但我正在寻找一些简单且已经内置到库中的东西.
在此先感谢您的帮助.
很抱歉,如果在某处明确回答这个问题,但我对我在线阅读的文档和文章感到有些困惑.
我看到我可以使用reset()函数释放shared_ptr中的内存(假设引用计数变为零),例如,
shared_ptr<int> x(new int(0));
x.reset(new int(1));
Run Code Online (Sandbox Code Playgroud)
我相信这会导致创建两个整数对象,并且在这两行的末尾,将从内存中删除等于零的整数.
但是,如果我使用以下代码块怎么办:
shared_ptr<int> x(new int(0));
x = shared_ptr<int>(new int(1));
Run Code Online (Sandbox Code Playgroud)
显然,现在*x == 1是真的,但原始整数对象(等于零)是从内存中删除还是我泄漏了那个内存?
在我看来,这将是赋值运算符减少shared_ptr的引用计数的问题,但是对源代码的一瞥似乎并不能解决我的问题.希望有经验或知识渊博的人可以帮助我.提前致谢.
我正在编写一个应用程序,其中相当多的计算时间将用于执行稀疏矩阵和向量的基本线性代数运算(加,乘,乘以矢量,乘以标量等).到目前为止,我们已经使用C++和Boost矩阵库构建了一个原型.
我正在考虑切换到Python,以便于编写应用程序本身,因为看起来Boost库(简单的C++线性代数库)无论如何都不是特别快.这是一个研究/概念验证应用程序,因此只要编码时间也显着减少,一些运行时速度的降低是可以接受的(因为我假设C++几乎总是优于Python).
基本上,我正在寻找之前使用过这些库的人的一般建议.但具体来说:
1)我找到了scipy.sparse和pySparse.这些(或其他图书馆)是推荐的吗?
2)推荐C++以外的哪些库超出Boost?我已经看过各种带有C接口的库,但如果我能获得相对较好的性能,我还是希望做一些复杂度低的东西.
3)最终,就线性代数运算的运行时速度而言,Python在某种程度上可以与C++相媲美吗?我将需要进行许多线性代数运算,如果减速很重要,那么我可能甚至不应该尝试进行这种切换.
提前感谢您提供任何帮助以及您可以提供的相关经验.
我知道如果我写一个类,我可以定义一个自定义打印函数,如下所示。
>>> class F:
... def __str__(self):
... return 'This describes the data of F.'
...
>>> f = F()
>>> print f
This describes the data of F.
Run Code Online (Sandbox Code Playgroud)
但是,如果我想对函数对象做同样的事情怎么办?例如,
>>> def f():
... pass
...
>>> g = f
>>> print g
<function f at 0x7f738d6da5f0>
Run Code Online (Sandbox Code Playgroud)
我想以某种方式指定打印的内容,而不是 '<function f at 0x7f738d6da5f0>'。这样做的动机是我将在列表中存储一堆函数对象,并且我想遍历列表并打印人类可读的函数类型描述,而不会增加额外的复杂性,例如,函数对象和字符串的元组。
在此先感谢您提供的任何帮助。
编辑:我改变了我的例子来反映我想要传达的内容,不幸的是我在输入“f”时输入了“f()”。我对函数对象的自定义标签感兴趣,而不是自定义返回(这很明显如何做)。对于由此造成的任何混淆,我们深表歉意。
我们有一个使用boost的矩阵和稀疏矩阵库的程序,我们正在尝试集成boost线程.但是,当我们从单线程应用程序迁移到多线程应用程序时,我们会遇到在单线程情况下不会发生的分段错误.
我们使用gdb(在Eclipse中)进行了调试,我发现在boost代码中的函数调用期间发生了seg错误,即我尝试访问稀疏矩阵的条目,堆栈跟踪进入boost代码并死于这些文件中的某些点(并非总是相同的点).
我很困惑,因为这些矩阵在各个线程中分配,所有共享资源都受互斥锁保护.此外,我不认为线程经常导致seg错误,只有多次访问和坏数据.但是,我显然没有多线程编程的经验,所以我希望在这个领域更有经验的人可以提供一些建议.
我正在使用boost托管make系统和一个示例编译命令
g++ -DNDEBUG -I"/usr/local/include/boost-1_38" -I/usr/local/include -I"/home/scandido/workspace/BigSHOT/src" -I"/home/scandido/workspace/BigSHOT/src/base" -O3 -Wall -c -fmessage-length=0 `freetype-config --cflags` -pthread -MMD -MP -MF"src/utils/timing_info.d" -MT"src/utils/timing_info.d" -o"src/utils/timing_info.o" "../src/utils/timing_info.cpp"
Run Code Online (Sandbox Code Playgroud)
和链接器命令是
g++ -L"/usr/local/lib" -L/usr/local/lib -o"BigSHOT" ./src/utils/timing_info.o ... many more objects ... ./src/base/pomdp/policy_fn/EventDriven.o ./src/base/pomdp/policy_fn/Greedy.o ./src/anotheralgorithm.o -lboost_serialization-gcc43-mt -lpthread -lboost_thread-gcc43-mt -lboost_program_options-gcc43-mt -lboost_iostreams-gcc43-mt -lpng -lpngwriter -lz -lfreetype
Run Code Online (Sandbox Code Playgroud)
这是一个seg错误的线程的堆栈跟踪:
Thread [5] (Suspended: Signal 'SIGSEGV' received. Description: Segmentation fault.)
17 boost::numeric::ublas::mapped_matrix<bool, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::map_std<unsigned long, bool, std::allocator<std::pair<unsigned long const, bool> > > >::operator() /usr/local/include/boost-1_38/boost/numeric/ublas/matrix_sparse.hpp:377 0x000000000041c328
16 BigSHOT::Fire1FireState::get_cell() /home/scandido/workspace/BigSHOT/src/systems/fire1/pomdp/Fire1State.cpp:51 0x0000000000419a75
15 BigSHOT::Fire1SquareRegionProbObsFn::operator() /home/scandido/workspace/BigSHOT/src/systems/fire1/obs_fn/Fire1SquareRegionProbObsFn.cpp:92 …
Run Code Online (Sandbox Code Playgroud)