This example computes the matrix multiplication of the vector of intensities for each voxel in the input dataset, producing a new dataset of the same size for the first 3 (spatial) axes, and with the number of volumes specified by the user. In this example, we generate a matrix of random numbers for illustrative purposes.
#include "image.h"
using namespace App;
{
AUTHOR =
"Joe Bloggs (joe.bloggs@acme.org)";
+ "compute matrix multiplication of each voxel vector of "
"values with matrix of random numbers";
+ Argument ("in", "the input image.").type_image_in ()
+ Argument ("out", "the output image.").type_image_out ();
+ Option ("size", "the number of rows of the matrix to be applied; "
"also the number of volumes in the output dataset (default = 10).")
+ Argument ("num").type_integer(0, 10);
}
typedef float compute_type;
class SharedInfo
{
public:
template <class HeaderType>
SharedInfo (const HeaderType& header, size_t num_el) :
A (num_el, header.size(3)) {
Math::RNG::Normal<value_type>
rng;
for (ssize_t i = 0; i < A.rows(); ++i)
for (ssize_t j = 0; j < A.cols(); ++j)
}
Eigen::MatrixXf A;
};
class MathMulFunctor {
public:
MathMulFunctor (const SharedInfo& shared) :
shared (shared),
vec_in (shared.A.cols()),
vec_out (shared.A.rows()) { }
template <class VoxeltypeIn, class VoxeltypeOut>
void operator() (VoxeltypeIn& in, VoxeltypeOut& out)
{
for (auto l = loop (in); l; ++l)
vec_in[in.index(3)] = in.value();
vec_out = shared.A * vec_in;
for (auto l = loop (out); l; ++l)
out.value() = vec_out[out.index(3)];
}
protected:
const SharedInfo& shared;
Eigen::VectorXf vec_in, vec_out;
};
{
Header header (in);
header.datatype() = DataType::Float32;
header.size(3) = nvol;
SharedInfo shared (in, nvol);
auto loop =
ThreadedLoop (
"performing matrix multiplication", in, 0, 3);
loop.run (MathMulFunctor (shared), in, out);
}
static Image open(const std::string &image_name, bool read_write_if_existing=false)
FORCE_INLINE LoopAlongAxes Loop()
OptionList OPTIONS
the options accepted by the command
vector< ParsedArgument > argument
the list of arguments parsed from the command-line
const char * AUTHOR
set the author of the command
T get_option_value(const std::string &name, const T default_value)
Returns the option value if set, and the default otherwise.
Description DESCRIPTION
additional description of the command over and above the synopsis
ArgumentList ARGUMENTS
the arguments expected by the command
thread_local Math::RNG rng
thread-local, but globally accessible RNG to vastly simplify multi-threading
std::unique_ptr< ImageIO::Base > create(Header &H)
MR::default_type value_type
ThreadedLoopRunOuter< decltype(Loop(vector< size_t >()))> ThreadedLoop(const HeaderType &source, const vector< size_t > &outer_axes, const vector< size_t > &inner_axes)
Multi-threaded loop object.