What is the Raphael.transformPath analogue in svg.js? - raphael

Raphael has a nifty function to transform one path to another:
R.transformPath = function (path, transform) {
return mapPath(path, toMatrix(path, transform));
}
Is there a similar function in svg.js?

To transform the path array you would do something along those lines:
const arr = path.array()
arr.map(segment => {
// ... add code to get the x and y of all the points used
// for a line it would be segment[1] and segment[2]
const {x, y} = new SVG.Point(segment[1], segment[2]).transform(transform)
return [segment[0], x, y]
})

Related

Calling numDeriv:hessian() with multiple-parameter-objective-function in Rcpp

My aim is to call the hessian() function from the numDeriv R package from a cpp file (using Rcpp).
A toy example:
I want to calculate a hessian of a one-dimensional function x^n at the point x=1 with parameter n=3.
R code:
H = call_1D_hessian_in_C(K=1)
print(H)
Cpp code:
double one_dimensional(double X, double N){
return pow(X,N);
}
// [[Rcpp::export]]
double call_1D_hessian_in_C(double K) {
Rcpp::Environment numDeriv("package:numDeriv");
Rcpp::Function hessian = numDeriv["hessian"];
double param = 3;
Rcpp::List hessian_results =
hessian(
Rcpp::_["func"] = Rcpp::InternalFunction(one_dimensional),
Rcpp::_["x"] = 1.0,
Rcpp::_["N"] = param
);
return hessian_results[0];
}
This works fine and I indeed get "6" at the output.
However my true goal is to calculate hessians of K-dimensional functions, therefore K=/=1. I try the following:
H = call_KD_hessian_in_C(K=2)
print(H)
And in Cpp:
NumericVector k_dimensional(NumericVector X, double N){
return pow(X,N);
}
// [[Rcpp::export]]
double call_KD_hessian_in_C(double K) {
Rcpp::Environment numDeriv("package:numDeriv");
Rcpp::Function hessian = numDeriv["hessian"];
double param = 3;
Rcpp::NumericVector x = rep(1.0,K);
Rcpp::List hessian_results =
hessian(
Rcpp::_["func"] = Rcpp::InternalFunction(k_dimensional),
Rcpp::_["x"] = x,
Rcpp::_["N"] = param
);
return hessian_results[0];
}
But now I get "invalid pointer" errors. A am not sure how to provide the hessian function call with a cpp function that takes a set of parameters to evaluate the partial derivatives at...
Couple of quick notes:
Try the implementation in R and then move it to C++.
Provides a reference point and makes sure that everything works as intended.
Search paths and names matter
Explicitly load numDeriv package before compiling.
Respect capitalization X vs. x.
Ensure output types are accurate
From ?numDeriv::hessian, the output type is an N x N Rcpp::NumericMatrix instead of Rcpp::List.
Implementing in R
Coding the example and running it in pure R would give:
k = 2
k_dimensional = function(x, N) {
x ^ N
}
numDeriv::hessian(k_dimensional, x = rep(1, k), N = 3)
Error in hessian.default(k_dimensional, x = rep(1, k), N = 3) :
Richardson method for hessian assumes a scalar valued function.
So, immediately, this means that the k_dimensional() function is missing a reduction down to a scalar (e.g. single value).
Environment Run Time Error with C++ variant
After compiling the original code, there is a runtime error or when the function was called the issue an issue appears. For example, we have:
Rcpp::sourceCpp("path/to/call_KD_hessian_in_C.cpp")
call_KD_hessian_in_C(K = 2)
This provides the error of:
Error in call_KD_hessian_in_C(2) :
Cannot convert object to an environment: [type=character; target=ENVSXP].
As we are using an R function found in a package not loaded by default, we must explicitly load it via library() or require() before calling the function.
Therefore, the process to avoid an environment issue should be:
# Compile the routine
Rcpp::sourceCpp("path/to/call_KD_hessian_in_C.cpp")
# Load numDeriv to ensure it is on the search path
library("numDeriv")
# Call function
call_KD_hessian_in_C(2)
Cleaned Up C++ Implementation
From prior discussion, note that we've:
Changed the function used with the hessian to be a scalar or single value, e.g. double, instead of a vector of values, e.g. NumericVector.
Ensured that before the function call the numDeriv R package is loaded.
Changed the return type expected from the hessian() function from Rcpp::List to Rcpp::NumericMatrix.
This results in the following C++ code:
#include <Rcpp.h>
double k_dimensional_cpp(Rcpp::NumericVector x, double N){
// ^^ Change return type from NumericVector to double
// Speed up the process by writing the _C++_ loop
// instead of relying on Rcpp sugar.
double total = 0;
for(int i = 0 ; i < x.size(); ++i) {
total += std::pow(x[i], N);
}
// Return the accumulated total
return total;
}
// [[Rcpp::export]]
Rcpp::NumericMatrix call_KD_hessian_in_C(double K) {
// Ensure that numDeriv package is loaded prior to calling this function
Rcpp::Environment numDeriv("package:numDeriv");
Rcpp::Function hessian = numDeriv["hessian"];
double param = 3;
Rcpp::NumericVector x = Rcpp::rep(1.0, K);
// Switched from Rcpp::List to Rcpp::NumericMatrix
Rcpp::NumericMatrix hessian_results =
hessian(
Rcpp::_["func"] = Rcpp::InternalFunction(k_dimensional_cpp),
Rcpp::_["x"] = x, // use lower case x to match function signature.
Rcpp::_["N"] = param
);
// Return the calculated hessian
return hessian_results;
}
Testing the routine gives:
# Ensure numDeriv is on search path
library("numDeriv")
# Call function
call_KD_hessian_in_C(K = 2)
# [,1] [,2]
# [1,] 6.000000e+00 3.162714e-12
# [2,] 3.162714e-12 6.000000e+00

Drawing a smooth curve in SFML

I am building a program in C++ using the SFML library which plots mathematical functions such as f(x)=sin(x). The code used to plot the points is:
VertexArray curve(PrimitiveType::LineStrip, 100);
for (int x = -50; x < 50; x++)
{
curve.append(Vertex(Vector2f(x,- sin(x))));
}
This code produces this plot:
As you can see the plot is not smooth and is made up of short lines due to sf::Linestrip. Is there a way to ( in SFML ) make this plot smoother ( e.g by shortening the line segments )?
Any feedback is much appreciated : ).
The easiest option is to increase the resolution of the lines - i.e. have more, smaller lines. This is simple to achieve and may be acceptable for your use case.
Sean Cline's example in the comments should be a good starting point:
for (float x = -50.0f; x < 50.0f; x += .25f)
{
curve.append(Vertex(Vector2f(x,- sin(x))));
}
You can then easily generalize the range and step and play around with the values:
float min_range = -200.f;
float max_range = 200.f;
float step = 0.5f;
for (float x = min_range; x < max_range ; x += step)
{
curve.append(Vertex(Vector2f(x,- sin(x))));
}
Finally, you can abstract this away behind a nice interface:
using precision = float;
struct plot_params
{
precision _min_range;
precision _max_range;
precision _step;
};
template <typename TFunction>
auto plot(const plot_params pp, TFunction&& f)
{
assert(pp._min_range <= pp._max_range);
assert(pp._step > 0.f);
VertexArray curve(PrimitiveType::LineStrip,
std::ceil((pp._max_range - pp._min_range) / pp._step);
for (auto x = pp._min_range; x < pp._max_range; x += pp._step)
{
curve.append(Vertex(f(x)));
}
}
And you can use plot as follows:
const auto my_params = []
{
plot_params pp;
pp._min_range = -200.f;
pp._max_range = 200.f;
pp._step = 0.5f;
return pp;
})();
auto curve = plot(my_params,
[](auto x){ return Vector2f(x,- sin(x)); });

Creating a Normal Distribution graph with Chart.js

I've been tasked with implementing a Normal Distribution graph. I was wondering if Chart.js offers this functionality right out of the box or if I will need to extend it. The graph in question is here
Thank you
It is unfortunately not possible with Chart.js, except if you create it by yourself.
But, I found a library called ChartNew.js (Github) that provides a lot of functionalities that are not available on Chart.js :
Chart.js has been completely rewritten since ChartNew.js has been developed; Both code are now completely different. Most of the functionalities inserted in the new version of Chart.js are also available in ChartNew.js
And this library provides a Gaussian Function (also called Normal Distribution) :
To do it, take a look at the sample given in the Github.
I'm sure it will suit you if you change some data.
This Implementation has been done using React. The functions below can still be used in other programming languages built on top of Javascript.
The only two inputs required to plot a Normal Distribution curve will be Mean and Standard deviation
Defining states for mean and standard deviation & states for X and Y arrays
const [bellMean, setBellMean] = useState<number>(12.2036); //example
const [bellStdev, setBellStdev] = useState<number>(0.0008); //example
const [bellXValues, setBellXValues] = useState<(number)[]>([]);
const [bellYValues, setBellYValues] = useState<(number | null)[]>([]);
To Get X values for bell curve (if not using react can get rid of useEffect)
useEffect(() => {
// defining chart limits between which the graph will be plotted
let lcl = bellMean - bellStdev * 6;
let ucl = bellMean + bellStdev * 6;
let ticks = [lcl];
let steps = 100; // steps corresponds to the size of the output array
let stepSize = Math.round(((ucl - lcl) / steps) * 10000) / 10000;
let tickVal = lcl;
for (let i = 0; i <= steps; i++) {
ticks.push(Math.round(tickVal * 10000) / 10000); // rounding off to 4 decimal places
tickVal = tickVal + stepSize;
}
setBellXValues(ticks); //array for X values
}, [bellMean, bellStdev]);
To Get Y values for Bell curve (if not using react can get rid of useEffect)
useEffect(() => {
// Using PDF function from vega-statistics instead of importing the whole library
const densityNormal = (value: number, mean: number, stdev: number) => {
const SQRT2PI = Math.sqrt(2 * Math.PI);
stdev = (stdev == null) ? 1 : stdev;
const z = (value - (mean || 0)) / stdev;
return Math.exp(-0.5 * z * z) / (stdev * SQRT2PI);
};
let YValues = bellXValues.map((item: number) => {
if (bellMean === null || bellStdev === undefined) {
return null;
} else {
const pdfValue = densityNormal(item, bellMean, bellStdev);
return pdfValue === Infinity ? null : pdfValue;
}
});
setBellYValues(YValues); // array for Y values
}, [bellXValues]);
The arrays for X and Y can be fed to labels and data props of chartjs as it is.

How to return a random parameter?

Template<typename T>
T Choose(T x, T y, T z)
{
//What code do i write so that when Choose() is called it would randomly
// return x y or z?
return;
}
For example if x=2, y=ten and z=4 then it would chose neither 2, ten or 4 to return
#include <stdlib.h>
Template<typename T>
T Choose(T x, T y, T z)
{
std::array<T*,3> temp{&x,&y,&z}; // or use std::reference_wrapper instead
auto rand_index=std::rand() % temp.size();
return *temp[rand_index];
}
Place all your parameters in a list. Pick a random number from start of list to end of list and return that parameter. Note, I am not familiar with writing C++ so please forgive the C# code here. This should be enough to give you an idea on how to complete this.
//Place all params in an array
var params = [x,y,z];
//Instantiate random number generator
var r = new Random();
//use 0 for min and 2 for max in this example and return
//the random array position
return params[r.Next(int min, int max)];

C++ Data Structure for storing 3 dimensions of floats

I've implemented a 3D strange attractor explorer which gives float XYZ outputs in the range 0-100, I now want to implement a colouring function for it based upon the displacement between two successive outputs.
I'm not sure of the data structure to use to store the colour values for each point, using a 3D array I'm limited to rounding to the nearest int which gives a very coarse colour scheme.
I'm vaguely aware of octtrees, are they suitable in this siutation?
EDIT: A little more explanation:
to generate the points i'm repeatedly running this:
(a,b,c,d are random floats in the range -3 to 3)
x = x2;
y = y2;
z = z2;
x2 = sin(a * y) - z * cos(b * x);
y2 = z2 * sin(c * x) - cos(d * y);
z2 = sin(x);
parr[i][0]=x;
parr[i][1]=y;
parr[i][2]=z;
which generates new positions for each axis each run, to colour the render I need to take the distance between two successive results, if I just do this with a distance calculation between each run then the colours fade back and forth in equilibrium so I need to take running average for each point and store it, using a 3dimenrsionl array is too coarse a colouring and I'm looking for advice on how to store the values at much smaller increments.
Maybe you could drop the 2-dim array off and use an 1-dim array of
struct ColoredPoint {
int x;
int y;
int z;
float color;
};
so that the code would look like
...
parr[i].x = x;
parr[i].y = y;
parr[i].z = z;
parr[i].color = some_computed_color;
(you may also wish to encapsulate the fields and use class ColoredPoint with access methods)
I'd probably think bout some kind of 3-d binary search tree.
template <class KEY, class VALUE>
class BinaryTree
{
// some implementation, probably available in libraries
public:
VALUE* Find(const KEY& key) const
{
// real implementation is needed here
return NULL;
}
};
// this tree nodes wil actually hold color
class BinaryTree1 : public BinaryTree<double, int>
{
};
class BinaryTree2 : public BinaryTree<double, BinaryTree1>
{
};
class BinaryTree3 : public BinaryTree<double, BinaryTree2>
{
};
And you function to retreive the color from this tree would look like that
bool GetColor(const BinaryTree3& tree, double dX, double dY, double& dZ, int& color)
{
BinaryTree2* pYTree = tree.Find(dX);
if( NULL == pYTree )
return false;
BinaryTree1* pZTree = pYTree->Find(dY);
if( NULL == pZTree )
return false;
int* pCol = pZTree->Find(dZ);
if( NULL == pCol )
return false;
color = *pCol;
return true;
}
Af course you will need to write the function that would add color to this tree, provided 3 coordinates X, Y and Z.
std::map appears to be a good candidate for base class.