Пример #1
0
static bool testRandomLinearity (Field                 &F,
				 const char            *text,
				 VectorStream<Row>    &A_stream,
				 VectorStream<Vector> &stream1,
				 VectorStream<Vector> &stream2)
{
	typedef SparseMatrix <Field, Row> Blackbox;

	ostringstream str;
	str << "Testing linearity (" << text << ")" << ends;
	commentator().start (str.str ().c_str (), "testRandomLinearity", stream1.m ());

	Blackbox A (F, A_stream);
	A_stream.reset ();

	ostream &report = commentator().report (Commentator::LEVEL_UNIMPORTANT, INTERNAL_DESCRIPTION);
	report << "Input matrix:" << endl;
	A.write (report, FORMAT_PRETTY);

	bool ret = testLinearity (F, A, stream1, stream2);

	stream1.reset ();
	stream2.reset ();

	commentator().stop (MSG_STATUS (ret), (const char *) 0, "testRandomLinearity");

	return ret;
}
Пример #2
0
void blockSizeTimingTest(Blackbox & A, size_t size)
{
	typedef typename Blackbox::MatrixDomain Dom;
	typedef typename Dom::Block Block;

	Dom MD = A.domain();
	size_t m = A.rowdim();

	LinBox::UserTimer timer;

	Block B(m,m), C(m,m), D(m,m);
	MD.random(B); MD.random(D);

	cout << size << "         " << m << "       ";

	timer.clear(); timer.start();
	A.unpackingApply(C,B,size);
	timer.stop();
	cout << timer << "              ";

	timer.clear(); timer.start();
	A.unpackingApplyTranspose(C,B,size);
	timer.stop();
	cout << timer << "               ";

	timer.clear(); timer.start();
	MD.mul(C,D,B);
	timer.stop();
	cout << timer << "     ";

	cout << endl;

} //blockSizeTimingTest()
Пример #3
0
bool testRandomApply1 (Field &F, const char *text, unsigned int iterations, VectorStream<Row> &A_stream)
{
	typedef SparseMatrix <Field, Row> Blackbox;

	ostringstream str;
	str << "Testing sparse random apply (1, " << text << ")" << ends;
	commentator().start (str.str ().c_str (), "testRandomApply1", iterations);

	bool ret = true;
	bool iter_passed;

	size_t i, k;

	VectorDomain<Field> VD (F);

	StandardBasisStream<Field, Vector> stream (F, A_stream.n ());
	Vector e_j, w;

	VectorWrapper::ensureDim (e_j, A_stream.n ());
	VectorWrapper::ensureDim (w, A_stream.m ());

	for (i = 0; i < iterations; i++) {
		commentator().startIteration ((unsigned)i);

		iter_passed = true;

		Blackbox A (F, A_stream);
		A_stream.reset ();

		ostream &report = commentator().report (Commentator::LEVEL_UNIMPORTANT, INTERNAL_DESCRIPTION);
		report << "Matrix:" << endl;
		A.write (report, FORMAT_PRETTY);

		stream.reset ();

		while (stream) {
			stream.next (e_j);

			A.apply (w, e_j);

			for (k = 0; k < A_stream.m (); k++)
				if (!F.areEqual (A.getEntry (k, stream.j () - 1), VectorWrapper::constRef<Field> (w, k)))
					ret = iter_passed = false;

			report << "Output vector " << stream.j () << ": ";
			VD.write (report, w) << endl;
		}

		if (!iter_passed)
			commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR)
				<< "ERROR: Output vectors were incorrect" << endl;

		commentator().stop ("done");
		commentator().progress ();
	}

	commentator().stop (MSG_STATUS (ret), (const char *) 0, "testRandomApply1");

	return ret;
}
Пример #4
0
void stressTest (Blackbox & A)
{
	//Note that the rowdim/coldim of A must be 30000
	typedef typename Blackbox::MatrixDomain Dom;
	typedef typename Dom::Block Block;

	Dom MD = A.domain();
	size_t m = 30000;
	size_t n = 2000;

	LinBox::UserTimer timer;

	Block B(m,n), C(m,n);
	MD.random(B);

	cout << "Test: 30000x30000 matrix multiplied by 30000x2000 matrix\nblock size = 2048\n\n";

	timer.clear(); timer.start();
	A.unpackingApply(C,B,2048);
	timer.stop();
	cout << "unpacking apply time: " << timer << endl;

	Block D(m,m); MD.random(D);

	timer.clear(); timer.start();
	MD.mul(C,D,B);
	timer.stop();
	cout << "domain mul time: " << timer << endl;

	cout << endl;
}  //end stressTest()
Пример #5
0
static bool testIdentityApply (Field &F, const char *text, VectorStream<Vector> &stream)
{
	typedef SparseMatrix <Field, Row> Blackbox;

	ostringstream str;
	str << "Testing identity apply (" << text << ")" << ends;
	commentator().start (str.str ().c_str (), "testIdentityApply", stream.m ());

	bool ret = true;
	bool iter_passed = true;

	VectorDomain<Field> VD (F);
	StandardBasisStream<Field, Row> f1 (F, stream.n ());
	Blackbox A (F, f1);

	ostream &report = commentator().report (Commentator::LEVEL_UNIMPORTANT, INTERNAL_DESCRIPTION);
	report << "Matrix:" << endl;
	A.write (report, FORMAT_PRETTY);

	Vector v, w;

	VectorWrapper::ensureDim (v, stream.n ());
	VectorWrapper::ensureDim (w, stream.n ());

	while (stream) {
		commentator().startIteration ((unsigned)stream.j ());

		iter_passed = true;

		stream.next (v);

		ostream &Report = commentator().report (Commentator::LEVEL_UNIMPORTANT, INTERNAL_DESCRIPTION);
		Report << "Input vector:  ";
		VD.write (Report, v);
		Report << endl;

		A.apply (w, v);

		Report << "Output vector: ";
		VD.write (Report, w);
		Report << endl;

		if (!VD.areEqual (v, w))
			ret = iter_passed = false;

		if (!iter_passed)
			commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR)
				<< "ERROR: Vectors are not equal" << endl;

		commentator().stop ("done");
		commentator().progress ();
	}

	stream.reset ();

	commentator().stop (MSG_STATUS (ret), (const char *) 0, "testIdentityApply");

	return ret;
}
Пример #6
0
void largeTest (Blackbox & A)
{
	//Use for large blackboxes
	typedef typename Blackbox::MatrixDomain Dom;
	typedef typename Dom::Block Block;

	Dom MD = A.domain();
	size_t m = A.coldim();
	size_t n = 2000;

	LinBox::UserTimer timer;

	Block B(m,n), C(m,n);
	MD.random(B);

	cout << "Test: " << A.rowdim() << "x" << m << "blackbox multiplied by " << m << "x" << n << "block\nblock size: 2048\n\n";

	timer.clear(); timer.start();
	A.unpackingApply(C,B,2048);
	timer.stop();
	cout << "unpacking apply time: " << timer << endl;
}  //end largeTest
Пример #7
0
static bool testTransposeBlackbox(Blackbox & A)
{
	typedef typename Blackbox::Field Field;
	commentator().start ("Testing Transpose", "testTranspose", 1);

	Transpose<Blackbox> B(A);

	bool ret = true, ret1;

	size_t m = A.rowdim(), n = A.coldim();
	const Field & F = A.field();
	VectorDomain<Field> VD (F);
	BlasVector<Field> x(F,n), y(F,m), z(F,n), w(F,m);

	VD.random(x);
	A.apply(y, x);
	B.applyTranspose(w, x);
	ret1 = VD.areEqual(y, w);
	if (not ret1) commentator().report() << "A and B^T disagree, FAIL" << std::endl;
	ret = ret and ret1;

	VD.random(y);
	A.applyTranspose(x, y);
	B.apply(z, y);
	ret1 = VD.areEqual(x, z);
	if (not ret1) commentator().report() << "A^T and B disagree, FAIL" << std::endl;
	ret = ret and ret1;

	ret1 = testBlackboxNoRW(B);
	if (not ret1) commentator().report() << "testBlackbox A^T FAIL" << std::endl;
	ret = ret and ret1;

	commentator().stop (MSG_STATUS (ret), (const char *) 0, "testTranspose");

	return ret;
}
Пример #8
0
void testTiming(Blackbox & A)
{
	typedef typename Blackbox::MatrixDomain Dom;
	typedef typename Dom::Block Block;

	Dom MD = A.domain();
	size_t m = A.rowdim(), n = A.coldim();
	size_t k = (m + n)/2;

	LinBox::UserTimer timer;

	Block B(n,k), C(m,k), D(k,m), E(k,n), F(k,k);
	MD.random(B); MD.random(D);

	vector<typename Dom::Element> v1, v2(m);
	typename Dom::RandIter r(MD);
	typename Dom::Element x;
	for(size_t i = 0; i != n; ++i){
		r.random(x);
		v1.push_back(x);
	}


	//Tests:
	cout << "Timing tests:" << endl << endl;

	timer.clear(); timer.start();
	for(size_t j = 0; j != m; ++j) A.apply(v2,v1);
	timer.stop();
	cout << "apply using vectors time: " << timer << endl;

	timer.clear(); timer.start();
	A.applyTranspose(C,B);
	timer.stop();
	cout << "apply using row addin time: " << timer << endl;

	timer.clear(); timer.start();
	A.unpackingApplyTranspose(C,B);
	timer.stop();
	cout << "apply using block axpy time: " << timer << endl;

	timer.clear(); timer.start();
	MD.mul(F, D, C);
	timer.stop();
	cout << "Matrix Domain mul time: " << timer << endl;

	cout << "End of timing tests" << endl << endl;

} // testTiming
Пример #9
0
bool testQLUP(const Field &F, size_t n, unsigned int iterations, int rseed, double sparsity = 0.05)
{
	bool res = true;

	commentator().start ("Testing Sparse elimination qlup", "testQLUP", iterations);

	size_t Ni = n;
	size_t Nj = n;
	integer card; F.cardinality(card);
	typename Field::RandIter generator (F,card,rseed);
	RandStream stream (F, generator, sparsity, n, n);

	for (size_t i = 0; i < iterations; ++i) {
		commentator().startIteration ((unsigned)i);


		stream.reset();

		Blackbox A (F, stream);

		std::ostream & report = commentator().report (Commentator::LEVEL_UNIMPORTANT, INTERNAL_DESCRIPTION);

		F.write( report ) << endl;
		A.write( report,Tag::FileFormat::Maple ) << endl;

		DenseVector<Field> u(F,Nj), v(F,Ni), w1(F,Nj), w2(F,Ni), w3(F,Ni), w(F,Ni);
		for(auto it=u.begin();it!=u.end();++it)
			generator.random (*it);


		A.apply(v,u);


		unsigned long rank;

		Method::SparseElimination SE;
		SE.strategy(Specifier::PIVOT_LINEAR);
		GaussDomain<Field> GD ( F );
		typename Field::Element determinant;
		Blackbox L(F, A.rowdim(), A.coldim());
		Permutation<Field> Q((int)A.rowdim(),F);
		Permutation<Field> P((int)A.coldim(),F);

		GD.QLUPin(rank, determinant,
			  Q, L, A, P,
			  A.rowdim(), A.coldim() );

		Q.apply(w, L.apply(w3, A.apply(w2, P.apply(w1,u) ) ) );

		bool error = false;
		auto itv=v.begin();
		auto itw=w.begin();
		for( ; itw!=w.end();++itw,++itv) {
			if (! F.areEqual(*itw,*itv) ) {
				error = true;
			}
		}

		if (error) {
			res = false;

			report << "ERROR : matrix(" << u.size() << ",1,[";
			for(auto itu=u.begin(); itu!=u.end();++itu)
				report << *itu << ',';
			report << "]);\n[";
			for(auto itv2=v.begin(); itv2!=v.end();++itv2)
				report << *itv2 << ' ';
			report << "]  !=  [";
			for(auto itw2=w.begin(); itw2!=w.end();++itw2)
				report << *itw2 << ' ';
			report << "]" << std::endl;


			report << "w1: [";
			for(auto itw2=w1.begin(); itw2!=w1.end();++itw2)
				report << *itw2 << ' ';
			report << "]" << std::endl;
			report << "w2: [";
			for(auto itw2=w2.begin(); itw2!=w2.end();++itw2)
				report << *itw2 << ' ';
			report << "]" << std::endl;
			report << "w3: [";
			for(auto itw2=w3.begin(); itw2!=w3.end();++itw2)
				report << *itw2 << ' ';
			report << "]" << std::endl;
		}

		commentator().stop ("done");
		commentator().progress ();
	}

	commentator().stop (MSG_STATUS (res), (const char *) 0, "testQLUP");

	return res;
}
Пример #10
0
static bool testNilpotentApply (Field &F, const char *text, VectorStream<Vector> &stream)
{
	typedef SparseMatrix <Field, Row> Blackbox;

	ostringstream str;
	str << "Testing nilpotent apply (" << text << ")" << ends;
	commentator().start (str.str ().c_str (), "testNilpotentApply", stream.m ());

	bool ret = true;
	bool even, iter_passed;

	StandardBasisStream<Field, Row> f1 (F, stream.n ());
	Row tmp;
	f1.next (tmp);  // Small trick: pull the first vector out to shift elements up one row
	Blackbox A (F, f1);

	ostream &report = commentator().report (Commentator::LEVEL_UNIMPORTANT, INTERNAL_DESCRIPTION);
	report << "Matrix:" << endl;
	A.write (report, FORMAT_PRETTY);

	size_t j;
	NonzeroRandIter<Field> r (F, typename Field::RandIter (F));

	VectorDomain<Field> VD (F);
	Vector v, w;

	VectorWrapper::ensureDim (v, stream.n ());
	VectorWrapper::ensureDim (w, stream.n ());

	while (stream) {
		commentator().startIteration ((unsigned)stream.j ());

		iter_passed = true;
		even = false;

		stream.next (v);

		// Make sure last element is nonzero
		r.random (VectorWrapper::ref<Field> (v, stream.n () - 1));

		ostream &Report = commentator().report (Commentator::LEVEL_UNIMPORTANT, INTERNAL_DESCRIPTION);
		Report << "Input vector:  ";
		VD.write (Report, v);
		Report << endl;

		commentator().start ("Applying vectors");

		for (j = 0; j < stream.n () - 1; j++, even = !even)
			if (even)
				A.apply (v, w);
			else
				A.apply (w, v);

		commentator().stop ("Done");

		Report << "A^(n-1) v:     ";
		VD.write (Report, even ? w : v);
		Report << endl;

		if (VD.isZero (even ? w : v)) {
			ret = false;
			commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR)
				<< "ERROR: A^(n-1) v is prematurely zero" << endl;
		}

		if (even)
			A.apply (v, w);
		else
			A.apply (w, v);

		Report << "A^n v:         ";
		VD.write (Report, even ? v : w);
		Report << endl;

		if (!VD.isZero (even ? v : w))
			ret = iter_passed = false;

		if (!iter_passed)
			commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR)
				<< "ERROR: A^n v is non-zero" << endl;

		commentator().stop ("done");
		commentator().progress ();
	}

	stream.reset ();

	commentator().stop (MSG_STATUS (ret), (const char *) 0, "testNilpotentApply");

	return ret;
}
Пример #11
0
bool testRandomApply2 (Field &F, const char *text, unsigned int iterations, VectorStream<Row> &A_stream)
{
	typedef SparseMatrix <Field, Row> Blackbox;

	ostringstream str;
	str << "Testing sparse random apply (2, " << text << ")" << ends;
	commentator().start (str.str ().c_str (), "testRandomApply2", iterations);

	bool ret = true;
	bool iter_passed;

	size_t i, j, k;

	VectorDomain<Field> VD (F);
	typename Field::RandIter r (F);
	typename Field::Element sum;

	integer c;
	// long width;

	F.characteristic (c);
	// width = logp (c, 10) + 1;

	Vector v, w;

	VectorWrapper::ensureDim (v, A_stream.n ());
	VectorWrapper::ensureDim (w, A_stream.m ());

	for (k = 0; k < A_stream.n (); k++)
		F.init (VectorWrapper::ref<Field> (v, k), 1);

	for (i = 0; i < iterations; i++) {
		commentator().startIteration ((unsigned)i);

		iter_passed = true;

		Blackbox A (F, A_stream);
		A_stream.reset ();

		ostream &report = commentator().report (Commentator::LEVEL_UNIMPORTANT, INTERNAL_DESCRIPTION);
		report << "Matrix:" << endl;
		A.write (report, FORMAT_PRETTY);

		A.apply (w, v);

		for (j = 0; j < A_stream.m (); j++) {
			F.init (sum, 0);

			for (k = 0; k < A_stream.n (); k++)
				F.addin (sum, A.getEntry (j, k));

			if (!F.areEqual (sum, VectorWrapper::constRef<Field> (w, j)))
				ret = iter_passed = false;
		}

		report << "Output vector: ";
		VD.write (report, w) << endl;

		if (!iter_passed)
			commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR)
				<< "ERROR: Output vector was incorrect" << endl;

		commentator().stop ("done");
		commentator().progress ();
	}

	commentator().stop (MSG_STATUS (ret), (const char *) 0, "testRandomApply2");

	return ret;
}
Пример #12
0
static bool testSingularInconsistentSolve (const Field          &F,
					   VectorStream<Vector> &stream1,
					   VectorStream<Vector> &stream2,
					   const char           *text,
					   MethodTraits          method)
{
	typedef Diagonal <Field, Vector> Blackbox;

	ostringstream str;
	str << "Testing singular inconsistent solve (" << text << ")";

	commentator().start (str.str ().c_str (), "testSingularInconsistentSolve", stream1.m ());

	VectorDomain<Field> VD (F);

	typename WiedemannSolver<Field>::ReturnStatus status;
	bool ret = true;

	Vector d1, d, b, x, y, u;
	typename Field::Element uTb;

	VectorWrapper::ensureDim (d, stream2.dim ());
	VectorWrapper::ensureDim (b, stream2.dim ());
	VectorWrapper::ensureDim (x, stream2.dim ());
	VectorWrapper::ensureDim (y, stream2.dim ());
	VectorWrapper::ensureDim (d1, stream1.dim ());

	MethodTraits traits (method);
	traits.preconditioner (MethodTraits::NONE);

	while (stream1 && stream2) {
		commentator().startIteration ((unsigned)stream1.j ());

		stream1.next (d1);
		stream2.next (b);

		VD.copy (d, d1);

		ostream &report = commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_DESCRIPTION);
		report << "Diagonal entries: ";
		VD.write (report, d);
		report << endl;

		report << "Right-hand side:  ";
		VD.write (report, b);
		report << endl;

		BlasVector<Field> dd(F,d);
		Blackbox D (dd);
		//Blackbox D (d);

		status = solve (D, x, b, u, F, traits);

		if (status == WiedemannSolver<Field>::INCONSISTENT) {
			D.applyTranspose (y, u);

			report << "Certificate of inconsistency found." << endl;

			report << "Certificate is: ";
			VD.write (report, u) << endl;

			report << "u^T A = ";
			VD.write (report, y) << endl;

			VD.dot (uTb, u, b);

			report << "u^T b = ";
			F.write (report, uTb) << endl;

			if (!VD.isZero (y)) {
				commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR)
					<< "ERROR: u is not in the right nullspace of D" << endl;
				ret = false;
			}

			if (F.isZero (uTb)) {
				commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR)
					<< "ERROR: u^T b = 0" << endl;
				ret = false;
			}
		}
		else if (status == WiedemannSolver<Field>::FAILED) {
			commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR)
				<< "ERROR: Solver refused to certify inconsistency" << endl;
			ret = false;
		}
		else {
			commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR)
				<< "ERROR: Solver gave solution even though system is inconsistent" << endl;
			ret = false;
		}

		commentator().stop ("done");
		commentator().progress ();
	}

	stream1.reset ();
	stream2.reset ();

	commentator().stop (MSG_STATUS (ret), (const char *) 0, "testSingularInconsistentSolve");

	return ret;
}
Пример #13
0
bool testAssociativity(Blackbox& A)
{
	typedef typename Blackbox::MatrixDomain Dom;
	Dom MD = A.domain();
	size_t m = A.rowdim(), n = A.coldim() - 100;
	size_t k = (m + n)/2;
	typename Dom::Block B(A.field(),k,m), C(A.field(),m,n);
	MD.random(B); MD.random(C);

	typename Dom::Block D(A.field(),m,n), E(A.field(),k,n);

	A.apply(D, C); // D = AC
	MD.mul(E,B,D); // E = B(AC)

	typename Dom::Block F(A.field(),k,m), G(A.field(),k,n);

	A.unpackingApplyTranspose(F,B); // F = BA
	MD.mul(G,F,C); // G = (BA)C
	return MD.areEqual(E,G);


} // testAssociativity
Пример #14
0
static bool testSingularConsistentSolve (const Field          &F,
					 unsigned int          n,
					 VectorStream<Vector> &stream1,
					 VectorStream<Vector> &stream2,
					 const char           *text,
					 MethodTraits          method)
{
	typedef Diagonal <Field, Vector> Blackbox;

	ostringstream str;
	str << "Testing singular consistent solve (" << text << ")";

	commentator().start (str.str ().c_str (), "testSingularConsistentSolve", stream1.m ());

	VectorDomain<Field> VD (F);

	bool ret = true;

	Vector d1, b1, d, b, x, y;

	VectorWrapper::ensureDim (d, n);
	VectorWrapper::ensureDim (b, n);
	VectorWrapper::ensureDim (x, n);
	VectorWrapper::ensureDim (y, n);
	VectorWrapper::ensureDim (d1, n);
	VectorWrapper::ensureDim (b1, n);

	MethodTraits traits (method);
	traits.preconditioner (MethodTraits::NO_PRECONDITIONER);

	while (stream1 && stream2) {
		commentator().startIteration ((unsigned)stream1.j ());

		ActivityState state = commentator().saveActivityState ();


		stream1.next (d1);
		stream2.next (b1);

		VD.copy (d, d1);
		VD.copy (b, b1);

		ostream &report = commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_DESCRIPTION);
		report << "Diagonal entries: ";
		VD.write (report, d);
		report << endl;

		report << "Right-hand side:  ";
		VD.write (report, b);
		report << endl;

		BlasVector<Field> dd(F,d);
		Blackbox D (dd);
		//Blackbox D (d);

		try {
			bool iter_passed = true;
			solve (D, x, b, F, traits);

			report << "System solution:  ";
			VD.write (report, x);
			report << endl;

			D.apply (y, x);

			report << "Output:           ";
			VD.write (report, y);
			report << endl;

			if (!VD.areEqual (y, b))
				ret = iter_passed = false;

			if (!iter_passed)
				commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR)
					<< "ERROR: Computed solution is incorrect" << endl;
		}
		catch (SolveFailed) {
			commentator().restoreActivityState (state);
			commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR)
				<< "ERROR: System solution failed" << endl;
			ret = false;
		}
		catch (InconsistentSystem<Vector> e) {
			commentator().restoreActivityState (state);
			ostream &Report = commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR);
			Report << "ERROR: Inconsistent system exception" << endl;

			Report << "Certificate is: ";
			VD.write (Report, e.u ()) << endl;

			ret = false;

			commentator().restoreActivityState (state);
		}

		commentator().stop ("done");
		commentator().progress ();
	}

	stream1.reset ();
	stream2.reset ();

	commentator().stop (MSG_STATUS (ret), (const char *) 0, "testSingularConsistentSolve");

	return ret;
}
Пример #15
0
void BlackboxResource::load(Blackbox& blackbox) {
  if (screen_resources == 0) {
    screen_resources = new ScreenResource[blackbox.screenCount()];
  }

  bt::Resource res(rc_file);

  menu_file = bt::expandTilde(res.read("session.menuFile",
                                       "Session.MenuFile",
                                       DEFAULTMENU));

  style_file = bt::expandTilde(res.read("session.styleFile",
                                        "Session.StyleFile",
                                        DEFAULTSTYLE));

  unsigned int maxcolors = res.read("session.maximumColors",
                                    "Session.MaximumColors",
                                    ~0u);
  if (maxcolors != ~0u)
    bt::Image::setMaximumColors(maxcolors);

  double_click_interval = res.read("session.doubleClickInterval",
                                   "Session.DoubleClickInterval",
                                   250l);

  auto_raise_delay.tv_usec = res.read("session.autoRaiseDelay",
                                      "Session.AutoRaiseDelay",
                                      400l);

  auto_raise_delay.tv_sec = auto_raise_delay.tv_usec / 1000;
  auto_raise_delay.tv_usec -= (auto_raise_delay.tv_sec * 1000);
  auto_raise_delay.tv_usec *= 1000;

  bt::DitherMode dither_mode;
  std::string str = res.read("session.imageDither",
                             "Session.ImageDither",
                             "OrderedDither");
  if (!strcasecmp("ordered", str.c_str()) ||
      !strcasecmp("fast", str.c_str()) ||
      !strcasecmp("ordereddither", str.c_str()) ||
      !strcasecmp("fastdither", str.c_str())) {
    dither_mode = bt::OrderedDither;
  } else if (!strcasecmp("floydsteinberg", str.c_str()) ||
             !strcasecmp("quality", str.c_str()) ||
             !strcasecmp("diffuse", str.c_str()) ||
             !strcasecmp("floydsteinbergdither", str.c_str()) ||
             !strcasecmp("qualitydither", str.c_str()) ||
             !strcasecmp("diffusedither", str.c_str())) {
    dither_mode = bt::FloydSteinbergDither;
  } else if (!strcasecmp("no", str.c_str()) ||
             !strcasecmp("nodither", str.c_str()) ||
             !strcasecmp("off", str.c_str())) {
    dither_mode = bt::NoDither;
  } else {
    dither_mode = bt::OrderedDither;
  }
  bt::Image::setDitherMode(dither_mode);

  _cursors.pointer =
    XCreateFontCursor(blackbox.XDisplay(), XC_left_ptr);
  _cursors.move =
    XCreateFontCursor(blackbox.XDisplay(), XC_fleur);
  _cursors.resize_top_left =
    XCreateFontCursor(blackbox.XDisplay(), XC_top_left_corner);
  _cursors.resize_bottom_left =
    XCreateFontCursor(blackbox.XDisplay(), XC_bottom_left_corner);
  _cursors.resize_top_right =
    XCreateFontCursor(blackbox.XDisplay(), XC_top_right_corner);
  _cursors.resize_bottom_right =
    XCreateFontCursor(blackbox.XDisplay(), XC_bottom_right_corner);

  // window options
  str = res.read("session.focusModel",
                 "Session.FocusModel",
                 res.read("session.screen0.focusModel",
                          "Session.Screen0.FocusModel",
                          "ClickToFocus"));
  if (str.find("ClickToFocus") != std::string::npos) {
    focus_model = ClickToFocusModel;
    auto_raise = false;
    click_raise = false;
  } else {
    focus_model = SloppyFocusModel;
    auto_raise = (str.find("AutoRaise") != std::string::npos);
    click_raise = (str.find("ClickRaise") != std::string::npos);
  }

  str = res.read("session.windowPlacement",
                 "Session.WindowPlacement",
                 res.read("session.screen0.windowPlacement",
                          "Session.Screen0.WindowPlacement",
                          "RowSmartPlacement"));
  if (strcasecmp(str.c_str(), "ColSmartPlacement") == 0)
    window_placement_policy = ColSmartPlacement;
  else if (strcasecmp(str.c_str(), "CenterPlacement") == 0)
    window_placement_policy = CenterPlacement;
  else if (strcasecmp(str.c_str(), "CascadePlacement") == 0)
    window_placement_policy = CascadePlacement;
  else
    window_placement_policy = RowSmartPlacement;

  str = res.read("session.rowPlacementDirection",
                 "Session.RowPlacementDirection",
                 res.read("session.screen0.rowPlacementDirection",
                          "Session.Screen0.RowPlacementDirection",
                          "lefttoright"));
  row_direction =
    (strcasecmp(str.c_str(), "righttoleft") == 0) ? RightLeft : LeftRight;

  str = res.read("session.colPlacementDirection",
                 "Session.ColPlacementDirection",
                 res.read("session.screen0.colPlacementDirection",
                          "Session.Screen0.ColPlacementDirection",
                          "toptobottom"));
  col_direction =
    (strcasecmp(str.c_str(), "bottomtotop") == 0) ? BottomTop : TopBottom;

  ignore_shaded =
    res.read("session.placementIgnoresShaded",
             "Session.placementIgnoresShaded",
             true);

  opaque_move =
    res.read("session.opaqueMove",
             "Session.OpaqueMove",
             true);
  opaque_resize =
    res.read("session.opaqueResize",
             "Session.OpaqueResize",
             true);
  full_max =
    res.read("session.fullMaximization",
             "Session.FullMaximization",
             res.read("session.screen0.fullMaximization",
                      "Session.Screen0.FullMaximization",
                      false));
  focus_new_windows =
    res.read("session.focusNewWindows",
             "Session.FocusNewWindows",
             res.read("session.screen0.focusNewWindows",
                      "Session.Screen0.FocusNewWindows",
                      true));
  focus_last_window_on_workspace =
    res.read("session.focusLastWindow",
             "Session.focusLastWindow",
             res.read("session.screen0.focusLastWindow",
                      "Session.Screen0.focusLastWindow",
                      true));
  change_workspace_with_mouse_wheel =
    res.read("session.changeWorkspaceWithMouseWheel",
             "session.changeWorkspaceWithMouseWheel",
             true);
  shade_window_with_mouse_wheel =
    res.read("session.shadeWindowWithMouseWheel",
             "session.shadeWindowWithMouseWheel",
             true);
  toolbar_actions_with_mouse_wheel =
    res.read("session.toolbarActionsWithMouseWheel",
             "session.toolbarActionsWithMouseWheel",
             true);
  allow_scroll_lock =
    res.read("session.disableBindingsWithScrollLock",
             "Session.disableBindingsWithScrollLock",
             res.read("session.screen0.disableBindingsWithScrollLock",
                      "Session.Screen0.disableBindingsWithScrollLock",
                      false));
  edge_snap_threshold =
    res.read("session.edgeSnapThreshold",
             "Session.EdgeSnapThreshold",
             res.read("session.screen0.edgeSnapThreshold",
                      "Session.Screen0.EdgeSnapThreshold",
                      0));
  window_snap_threshold =
    res.read("session.windowSnapThreshold",
             "Session.windowSnapThreshold",
             0);

  for (unsigned int i = 0; i < blackbox.screenCount(); ++i)
    screen_resources[i].load(res, i);
}
Пример #16
0
int main (int argc, char **argv)
{
	//     commentator().setMaxDetailLevel (-1);
	//     commentator().setMaxDepth (-1);
	//     commentator().setReportStream (std::cerr);


	if (argc < 2 || argc > 4) {
		std::cerr << "Usage: omp_smithvalence <matrix-file-in-supported-format> [-ata|-aat|valence] [coprime]" << std::endl;
        std::cerr << "       Optional parameters valence and coprime are integers." << std::endl;
        std::cerr << "       Prime factors of valence will be used for local computation." << std::endl;
        std::cerr << "       coprime will be used for overall rank computation." << std::endl;
		return -1;
	}

	std::ifstream input (argv[1]);
	if (!input) { std::cerr << "Error opening matrix file " << argv[1] << std::endl; return -1; }

	Givaro::ZRing<Integer> ZZ;
	MatrixStream< Givaro::ZRing<Integer> > ms( ZZ, input );
	typedef SparseMatrix<Givaro::ZRing<Integer>>  Blackbox;
	Blackbox A (ms);
	input.close();

	std::cout << "A is " << A.rowdim() << " by " << A.coldim() << std::endl;

	Givaro::ZRing<Integer>::Element val_A;

	LinBox::Timer chrono; chrono.start();
	if (argc >= 3) {
		Transpose<Blackbox> T(&A);
		if (strcmp(argv[2],"-ata") == 0) {
			Compose< Transpose<Blackbox>, Blackbox > C (&T, &A);
			std::cout << "A^T A is " << C.rowdim() << " by " << C.coldim() << std::endl;
			valence(val_A, C);
		}
		else if (strcmp(argv[2],"-aat") == 0) {
			Compose< Blackbox, Transpose<Blackbox> > C (&A, &T);
			std::cout << "A A^T is " << C.rowdim() << " by " << C.coldim() << std::endl;
			valence(val_A, C);
		}
		else {
			std::cout << "Suppose primes are contained in " << argv[2] << std::endl;
			val_A = LinBox::Integer(argv[2]);
		}
	}
	else {
		if (A.rowdim() != A.coldim()) {
			std::cerr << "Valence works only on square matrices, try either to change the dimension in the matrix file, or to compute the valence of A A^T or A^T A, via the -aat or -ata options."  << std::endl;
			exit(0);
		}
		else
			valence (val_A, A);
	}

	std::cout << "Valence is " << val_A << std::endl;

	std::vector<Givaro::Integer> Moduli;
	std::vector<size_t> exponents;
	Givaro::IntFactorDom<> FTD;

	typedef std::pair<Givaro::Integer,unsigned long> PairIntRk;
	std::vector< PairIntRk > smith;


Givaro::Integer coprimeV=2;
	if (argc >= 4) {
		coprimeV =Givaro::Integer(argv[3]);
	}
	while ( gcd(val_A,coprimeV) > 1 ) {
		FTD.nextprimein(coprimeV);
	}

	if (argc >= 4) {
		std::cout << "Suppose " << argv[3] << " is coprime with Smith form" << std::endl;
	}

	std::cout << "Integer rank: " << std::endl;

	unsigned long coprimeR; LRank(coprimeR, argv[1], coprimeV);
	smith.push_back(PairIntRk(coprimeV, coprimeR));
	//         std::cerr << "Rank mod " << coprimeV << " is " << coprimeR << std::endl;

	std::cout << "Some factors (50000 factoring loop bound): ";
	FTD.set(Moduli, exponents, val_A, 50000);
	std::vector<size_t>::const_iterator eit=exponents.begin();
	for(std::vector<Givaro::Integer>::const_iterator mit=Moduli.begin();
	    mit != Moduli.end(); ++mit,++eit)
		std::cout << *mit << '^' << *eit << ' ';
	std::cout << std::endl;

	std::vector<Givaro::Integer> SmithDiagonal(coprimeR,Givaro::Integer(1));

	std::cout << "num procs: " << omp_get_num_procs() << std::endl;
	std::cout << "max threads: " << omp_get_max_threads() << std::endl;
#pragma omp parallel for shared(SmithDiagonal, Moduli, coprimeR)
	for(size_t j=0; j<Moduli.size(); ++j) {
		unsigned long r; LRank(r, argv[1], Moduli[j]);
		std::cerr << "Rank mod " << Moduli[j] << " is " << r << " on thread: " << omp_get_thread_num() << std::endl;
		smith.push_back(PairIntRk( Moduli[j], r));
		for(size_t i=r; i < coprimeR; ++i)
			SmithDiagonal[i] *= Moduli[j];
	}


	/*
	   for(std::vector<Givaro::Integer>::const_iterator mit=Moduli.begin();
	   mit != Moduli.end(); ++mit) {
	   unsigned long r; LRank(r, argv[1], *mit);
	   std::cerr << "Rank mod " << *mit << " is " << r << std::endl;
	   smith.push_back(PairIntRk(*mit, r));
	   for(size_t i=r; i < coprimeR; ++i)
	   SmithDiagonal[i] *= *mit;
	   }
	   */

	eit=exponents.begin();
	std::vector<PairIntRk>::const_iterator sit=smith.begin();
	for( ++sit; sit != smith.end(); ++sit, ++eit) {
            if (sit->second != coprimeR) {
                std::vector<size_t> ranks;
                ranks.push_back(sit->second);
                size_t effexp;
                if (*eit > 1) {
                    if (sit->first == 2)
                        PRankPowerOfTwo(ranks, effexp, argv[1], *eit, coprimeR);
                    else
                        PRank(ranks, effexp, argv[1], sit->first, *eit, coprimeR);
                }
                else {
			// if (sit->first == 2)
			PRank(ranks, effexp, argv[1], sit->first, 2, coprimeR);
			// else
			// PRank(ranks, effexp, argv[1], sit->first, 2, coprimeR);
		}
                if (ranks.size() == 1) ranks.push_back(coprimeR);

                if (effexp < *eit) {
                    for(size_t expo = effexp<<1; ranks.back() < coprimeR; expo<<=1) {
                        if (sit->first == 2)
                            PRankIntegerPowerOfTwo(ranks, argv[1], expo, coprimeR);
                        else
                            PRankInteger(ranks, argv[1], sit->first, expo, coprimeR);
                    }
                } else {

                    for(size_t expo = (*eit)<<1; ranks.back() < coprimeR; expo<<=1) {
                        if (sit->first == 2)
                            PRankPowerOfTwo(ranks, effexp, argv[1], expo, coprimeR);
                        else
                            PRank(ranks, effexp, argv[1], sit->first, expo, coprimeR);
                        if (ranks.size() < expo) {
                            std::cerr << "It seems we need a larger prime power, it will take longer ..." << std::endl;
                                // break;
                            if (sit->first == 2)
                                PRankIntegerPowerOfTwo(ranks, argv[1], expo, coprimeR);
                            else
                                PRankInteger(ranks, argv[1], sit->first, expo, coprimeR);
                        }
                    }
                }

                std::vector<size_t>::const_iterator rit=ranks.begin();
// 			unsigned long modrank = *rit;
                for(++rit; rit!= ranks.end(); ++rit) {
                    if ((*rit)>= coprimeR) break;
                    for(size_t i=(*rit); i < coprimeR; ++i)
                        SmithDiagonal[i] *= sit->first;
// 				modrank = *rit;
                }
            }
	}

Givaro::Integer si=1;
	size_t num=0;
	for( std::vector<Givaro::Integer>::const_iterator dit=SmithDiagonal.begin();
	     dit != SmithDiagonal.end(); ++dit) {
		if (*dit == si) ++num;
		else {
			std::cerr << '[' << si << ',' << num << "] ";
			num=1;
			si = *dit;
		}
	}
	std::cerr << '[' << si << ',' << num << "] " << std::endl;
	chrono.stop();
	std::cerr << chrono << std::endl;


	return 0;
}
Пример #17
0
bool testQLUPnullspace(const Field &F, size_t n, unsigned int iterations, int rseed, double sparsity = 0.05)
{
	bool res = true;

	commentator().start ("Testing Sparse elimination qlup nullspacebasis", "testQLUPnullspace", iterations);

	size_t Ni = n;
	size_t Nj = n;
	integer card; F.cardinality(card);
	typename Field::RandIter generator (F,card,rseed);
	RandStream stream (F, generator, sparsity, n, n, rseed);

	for (size_t i = 0; i < iterations; ++i) {
		commentator().startIteration ((unsigned)i);

		stream.reset();
		Blackbox A (F, stream);

		std::ostream & report = commentator().report (Commentator::LEVEL_UNIMPORTANT, INTERNAL_DESCRIPTION);

		F.write( report ) << endl;
		A.write( report, Tag::FileFormat::Maple ) << endl;


		Method::SparseElimination SE;
		SE.strategy(Specifier::PIVOT_LINEAR);
		GaussDomain<Field> GD ( F );

		Blackbox CopyA ( A );
		Blackbox X(F, A.coldim(), A.coldim() );

		GD.nullspacebasisin(X, CopyA );

		size_t nullity = X.coldim();

		DenseVector<Field> u(F,nullity);
		for(auto it=u.begin();it!=u.end();++it)
			generator.random (*it);
		DenseVector<Field> v(F,Nj);
		X.apply(v,u);
		report << "Random combination of the rows of the NullSpace basis" << std::endl;

		DenseVector<Field> w(F,Ni);
		A.apply(w, v);

		VectorDomain<Field> VD(F);

		if (! VD.isZero(w)) {
			res=false;
			A.write( report, Tag::FileFormat::Maple ) << endl;

			report << "ERROR u: matrix(" << u.size() << ",1,[";
			for(auto itu=u.begin(); itu!=u.end();++itu)
				report << *itu << ',';
			report << "]);\n[";
			report << "ERROR v: matrix(" << v.size() << ",1,[";
			for(auto itu=v.begin(); itu!=v.end();++itu)
				report << *itu << ',';
			report << "]);\n[";
			for(auto itv=w.begin(); itv!=w.end();++itv)
				report << *itv << ' ';
			report << "]  !=  0" << std::endl;

		}

		commentator().stop ("done");
		commentator().progress ();
	}

	commentator().stop (MSG_STATUS (res), (const char *) 0, "testQLUPnullspace");

	return res;
}
Пример #18
0
bool testQLUPsolve(const Field &F, size_t n, unsigned int iterations, int rseed, double sparsity = 0.05)
{
	bool res = true;

	commentator().start ("Testing Sparse elimination qlup solve", "testQLUPsolve", iterations);

	size_t Ni = n;
	size_t Nj = n;
	integer card; F.cardinality(card);
	typename Field::RandIter generator (F,card,rseed);
	RandStream stream (F, generator, sparsity, n, n);

	GF2 F2;
	GF2::RandIter bitgenerator(F2,2,rseed);
	// GF2::Element randomsolve;

	for (size_t i = 0; i < iterations; ++i) {
		commentator().startIteration ((unsigned)i);

		stream.reset();
		Blackbox A (F, stream);

		std::ostream & report = commentator().report (Commentator::LEVEL_UNIMPORTANT, INTERNAL_DESCRIPTION);

		F.write( report ) << endl;
		A.write( report, Tag::FileFormat::Maple ) << endl;

		DenseVector<Field> u(F,Nj), v(F,Ni), x(F,Nj), y(F,Ni);
		for(auto it=u.begin();it!=u.end();++it)
			generator.random (*it);

		A.apply(v,u);


		Method::SparseElimination SE;
		SE.strategy(Specifier::PIVOT_LINEAR);
		GaussDomain<Field> GD ( F );

		Blackbox CopyA ( A );

		GD.solvein(x, A, v /*, bitgenerator .random(randomsolve) */ );
		// report << "Random solving: " << randomsolve << std::endl;

		CopyA.apply(y, x);

		VectorDomain<Field> VD(F);


		if (! VD.areEqual(v,y)) {
			res=false;
			A.write( report, Tag::FileFormat::Maple ) << endl;

			report << "ERROR v: matrix(" << v.size() << ",1,[";
			for(auto itu=v.begin(); itu!=v.end();++itu)
				report << *itu << ',';
			report << "]);\n[";
			report << "ERROR y: matrix(" << y.size() << ",1,[";
			for(auto itu=y.begin(); itu!=y.end();++itu)
				report << *itu << ',';
			report << "]);\n[";
			for(auto itv=x.begin(); itv!=x.end();++itv)
				report << *itv << ' ';
			report << "]  !=  [";
			for(auto itw=y.begin(); itw!=y.end();++itw)
				report << *itw << ' ';
			report << "]" << std::endl;

		}

		commentator().stop ("done");
		commentator().progress ();
	}

	commentator().stop (MSG_STATUS (res), (const char *) 0, "testQLUPsolve");

	return res;
}
Пример #19
0
static bool testNonsingularSolve (const Field          &F,
				  VectorStream<Vector> &stream1,
				  VectorStream<Vector> &stream2,
				  const char           *text,
				  MethodTraits          method)
{
	typedef Diagonal <Field> Blackbox;

	ostringstream str;
	str << "Testing nonsingular solve (" << text << ")";

	commentator().start (str.str ().c_str (), "testNonsingularSolve", stream1.m ());

	VectorDomain<Field> VD (F);

	bool ret = true;

	size_t n= stream1.n ();
	Vector d(F,n), b(F,n), x(F,n), y(F,n);

	// VectorWrapper::ensureDim (d, stream1.n ());
	// VectorWrapper::ensureDim (b, stream1.n ());
	// VectorWrapper::ensureDim (x, stream1.n ());
	// VectorWrapper::ensureDim (y, stream1.n ());

	MethodTraits traits (method);

	while (stream1 && stream2) {
		commentator().startIteration ((unsigned)stream1.j ());

		ActivityState state = commentator().saveActivityState ();

		bool iter_passed = true;

		stream1.next (d);
		stream2.next (b);

		ostream &report = commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_DESCRIPTION);
		report << "Diagonal entries: ";
		VD.write (report, d);
		report << endl;

		report << "Right-hand side:  ";
		VD.write (report, b);
		report << endl;

		BlasVector<Field> dd(F,d);
		Blackbox D (dd);

		try {
			solve (x, D, b, method);
		}
		catch (SolveFailed) {
			commentator().restoreActivityState (state);
			commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR)
				<< "ERROR: System solution failed" << endl;
			ret = iter_passed = false;
		}
		catch (InconsistentSystem<Vector> e) {
			commentator().restoreActivityState (state);
			commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR)
				<< "ERROR: solve reported inconsistent system" << endl;
			ret = iter_passed = false;
		}

		if (iter_passed) {
			report << "System solution:  ";
			VD.write (report, x);
			report << endl;

			D.apply (y, x);

			report << "Output:           ";
			VD.write (report, y);
			report << endl;

			if (!VD.areEqual (y, b))
				ret = iter_passed = false;

			if (!iter_passed)
				commentator().report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR)
					<< "ERROR: Computed solution is incorrect" << endl;
		}

		commentator().stop ("done");
		commentator().progress ();
	}

	stream1.reset ();
	stream2.reset ();

	commentator().stop (MSG_STATUS (ret), (const char *) 0, "testNonsingularSolve");

	return ret;
}
Пример #20
0
void BlackboxResource::save(Blackbox& blackbox) {
  bt::Resource res;

  {
    if (bt::Resource(rc_file).read("session.cacheLife",
                                   "Session.CacheLife",
                                   -1) == -1) {
      res.merge(rc_file);
    } else {
      // we are converting from 0.65.0 to 0.70.0, let's take the liberty
      // of generating a brand new rc file to make sure we throw out
      // undeeded entries
    }
  }

  res.write("session.menuFile", menuFilename());

  res.write("session.styleFile", styleFilename());

  res.write("session.maximumColors",  bt::Image::maximumColors());

  res.write("session.doubleClickInterval", double_click_interval);

  res.write("session.autoRaiseDelay", ((auto_raise_delay.tv_sec * 1000ul) +
                                       (auto_raise_delay.tv_usec / 1000ul)));

  std::string str;
  switch (bt::Image::ditherMode()) {
  case bt::OrderedDither:        str = "OrderedDither";        break;
  case bt::FloydSteinbergDither: str = "FloydSteinbergDither"; break;
  default:                       str = "NoDither";             break;
  }
  res.write("session.imageDither", str);

  // window options
  switch (focus_model) {
  case SloppyFocusModel:
  default:
    str = "SloppyFocus";
    if (auto_raise)
      str += " AutoRaise";
    if (click_raise)
      str += " ClickRaise";
    break;
  case ClickToFocusModel:
    str = "ClickToFocus";
    break;
  }
  res.write("session.focusModel", str);

  switch (window_placement_policy) {
  case CascadePlacement:
    str = "CascadePlacement";
    break;
  case CenterPlacement:
    str = "CenterPlacement";
    break;
  case ColSmartPlacement:
    str = "ColSmartPlacement";
    break;
  case RowSmartPlacement:
  default:
    str = "RowSmartPlacement";
    break;
  }
  res.write("session.windowPlacement", str);
  res.write("session.rowPlacementDirection",
            (row_direction == LeftRight)
            ? "LeftToRight"
            : "RightToLeft");
  res.write("session.colPlacementDirection",
            (col_direction == TopBottom)
            ? "TopToBottom"
            : "BottomToTop");

  res.write("session.placementIgnoresShaded", ignore_shaded);

  res.write("session.opaqueMove", opaque_move);
  res.write("session.opaqueResize", opaque_resize);
  res.write("session.fullMaximization", full_max);
  res.write("session.focusNewWindows", focus_new_windows);
  res.write("session.focusLastWindow", focus_last_window_on_workspace);
  res.write("session.changeWorkspaceWithMouseWheel",
            change_workspace_with_mouse_wheel);
  res.write("session.shadeWindowWithMouseWheel",
            shade_window_with_mouse_wheel);
  res.write("session.toolbarActionsWithMouseWheel",
            toolbar_actions_with_mouse_wheel);
  res.write("session.disableBindingsWithScrollLock", allow_scroll_lock);
  res.write("session.edgeSnapThreshold", edge_snap_threshold);
  res.write("session.windowSnapThreshold", window_snap_threshold);

  for (unsigned int i = 0; i < blackbox.screenCount(); ++i)
    screen_resources[i].save(res, blackbox.screenNumber(i));

  res.save(rc_file);
}