Suppose I have the following c++ code in a file named test.cpp
#include <Rcpp.h>
//[[Rcpp::export]]
Rcpp::NumericMatrix MyAbar (const Rcpp::NumericMatrix & x, int T){
unsigned int outrows = x.nrow(), i = 0, j = 0;
double d;
Rcpp::NumericMatrix out(outrows,outrows);
// Rcpp::LogicalVector comp;
for (i = 0; i < outrows - 1; i++){
Rcpp::NumericVector v1 = x.row(i);
Rcpp::NumericVector ans(outrows);
for (j = i + 1; j < outrows ; j ++){
d = mean(Rcpp::runif( T ) < x(i,j));
out(j,i)=d;
out(i,j)=d;
}
}
return out;
}
I know with the following command, I can have my own package
Rcpp.package.skeleton("test",cpp_files = "~/Desktop/test.cpp")
However, what if I want to combine the following R function which call the Rcpp-function into the package
random = function(A, T){
if (!is.matrix(A)){
A = Reduce("+",A)/T
}
# global constant and threshold
n = nrow(A)
B_0 = 3
w = min(sqrt(n),sqrt(T * log(n)))
q = B_0 * log(n) / (sqrt(n) * w)
A2 = MyAbar(A)
diag(A2) <- NA
K = A2 <= rowQuantiles(A2, probs=q, na.rm =TRUE)
diag(K) = FALSE
P = K %*% A * ( 1/(rowSums(K) + 1e-10))
return( (P + t(P))*0.5 )
}
How can i make it?
So you are asking how to make an R package? There are many good tutorials.
To a first approximation:
copy your file into, say, file R/random.R
deal with a help file for your function, either manually by writing man/random.Rd or by learning package roxygen2
make sure you know what NAMESPACE is for and that DESCRIPTION is right
I have changed my post and posted the whole of my code! Could someone tell me how can I optimize it?
import Base: *, +, -, /, ^
using Images
const Π = convert(Float64, π)
#define vector
mutable struct Vec3
x::Float64
y::Float64
z::Float64
end
function +(u::Vec3, v::Vec3)
Vec3(u.x+v.x, u.y+v.y, u.z+v.z)
end
function -(u::Vec3, v::Vec3)
Vec3(u.x-v.x, u.y-v.y, u.z-v.z)
end
function /(u::Vec3, v::Float64)
Vec3(u.x/v, u.y/v, u.z/v)
end
function *(u, v::Vec3)
if typeof(u) == Float64
Vec3(u*v.x, u*v.y, u*v.z)
elseif typeof(u) == Vec3
Vec3(u.x*v.x, u.y*v.y, u.z*v.z)
end
end
function ^(u::Vec3, v::Float64)
Vec3(u.x^v, u.y^v, u.z^v)
end
function dot(u::Vec3, v::Vec3)
u.x*v.x + u.y*v.y + u.z*v.z
end
function normalize(u::Vec3)
u/sqrt(dot(u,u))
end
function cross(u::Vec3, v::Vec3)
Vec3(u.y*v.z - v.y*u.z, u.z*v.x - v.z*u.x, u.x*v.y - v.x*u.y)
end
function gamma(u::Vec3)
Vec3(u.x^(1/2.2), u.y^(1/2.2), u.z^(1/2.2))
end
function clamp(u::Vec3)
u.x = u.x <= 1 ? u.x : 1
u.y = u.y <= 1 ? u.y : 1
u.z = u.z <= 1 ? u.z : 1
u
end
#define ray
struct Ray
s::Vec3
d::Vec3
end
#define planes
struct xyRect
z; x1; x2; y1; y2::Float64
normal; emittance; reflectance::Vec3
isLight::Bool
end
struct xzRect
y; x1; x2; z1; z2::Float64
normal; emittance; reflectance::Vec3
isLight::Bool
end
struct yzRect
x; y1; y2; z1; z2::Float64
normal; emittance; reflectance::Vec3
isLight::Bool
end
#define sphere
mutable struct Sphere
radius::Float64
center; normal; emittance; reflectance::Vec3
isLight::Bool
end
#define empty object
struct Empty
normal; emittance; reflectance::Vec3
end
#define surfaces
Surfaces = Union{xyRect, xzRect, yzRect, Sphere}
#define intersection function
function intersect(surface::Surfaces, ray::Ray)
if typeof(surface) == xyRect
t = (surface.z - ray.s.z)/ray.d.z
if surface.x1 < ray.s.x + t*ray.d.x < surface.x2 && surface.y1 < ray.s.y + t*ray.d.y < surface.y2 && t > 0
t
else
Inf
end
elseif typeof(surface) == xzRect
t = (surface.y - ray.s.y)/ray.d.y
if surface.x1 < ray.s.x + t*ray.d.x < surface.x2 && surface.z1 < ray.s.z + t*ray.d.z < surface.z2 && t > 0
t
else
Inf
end
elseif typeof(surface) == yzRect
t = (surface.x - ray.s.x)/ray.d.x
if surface.y1 < ray.s.y + t*ray.d.y < surface.y2 && surface.z1 < ray.s.z + t*ray.d.z < surface.z2 && t > 0
t
else
Inf
end
elseif typeof(surface) == Sphere
a = dot(ray.d, ray.d)
b = 2dot(ray.d, ray.s - surface.center)
c = dot(ray.s - surface.center, ray.s - surface.center) - surface.radius*surface.radius
Δ = b*b - 4*a*c
if Δ > 0
Δ = sqrt(Δ)
t1 = 0.5(-b-Δ)/a
t2 = 0.5(-b+Δ)/a
if t1 > 0
surface.normal = normalize(ray.s + t1*ray.d - surface.center)
t1
elseif t2 > 0
surface.normal = normalize(ray.s + t2*ray.d - surface.center)
t2
else
Inf
end
else
Inf
end
end
end
#define nearest function
function nearest(surfaces::Array{Surfaces, 1}, ray::Ray, tMin::Float64)
hitSurface = Empty(Vec3(0,0,0), Vec3(0,0,0), Vec3(0,0,0))
for surface in surfaces
t = intersect(surface, ray)
if t < tMin
tMin = t
hitSurface = surface
end
end
tMin, hitSurface
end
#cosine weighted sampling of hemisphere
function hemiRand(n::Vec3)
ξ1 = rand()
ξ2 = rand()
x = cos(2π*ξ2)*sqrt(ξ1)
y = sin(2π*ξ2)*sqrt(ξ1)
z = sqrt(1-ξ1)
r = normalize(Vec3(2rand()-1, 2rand()-1, 2rand()-1))
b = cross(n,r)
t = cross(n,b)
Vec3(x*t.x + y*b.x + z*n.x, x*t.y + y*b.y + z*n.y, x*t.z + y*b.z + z*n.z)
end
#trace the path
function trace(surfaces::Array{Surfaces, 1}, ray::Ray, depth::Int64, maxDepth::Int64)
if depth >= maxDepth
return Vec3(0,0,0)
end
t, material = nearest(surfaces, ray, Inf)
if typeof(material) == Empty
return Vec3(0,0,0)
end
if material.isLight == true
return material.emittance
end
ρ = material.reflectance
BRDF = ρ/Π
n = material.normal
R = hemiRand(n)
In = trace(surfaces, Ray(ray.s + t*ray.d, R), depth+1, maxDepth)
return Π*BRDF*In
end
#define camera
struct Camera
eye; v_up; N::Vec3
fov; aspect; distance::Float64
end
#render function
function render(surfaces::Array{Surfaces,1},camera::Camera,xRes::Int64,yRes::Int64,numSamples::Int64,maxDepth::Int64)
n = normalize(camera.N)
e = camera.eye
c = e - camera.distance*n
θ = camera.fov*(π/180)
H = 2*camera.distance*tan(θ/2)
W = H*camera.aspect
u = normalize(cross(camera.v_up,n))
v = cross(n,u)
img = zeros(3, xRes, yRes)
pixHeight = H/yRes
pixWidth = W/xRes
L = c - 0.5*W*u - 0.5*H*v
for i=1:xRes
for j=1:yRes
cl = Vec3(0,0,0)
for s=1:numSamples
pt = L + (i-rand())*pixWidth*u + (yRes-j+rand())*pixHeight*v
cl = cl + trace(surfaces, Ray(e, pt-e), 0, maxDepth)
end
cl = gamma(clamp(cl/convert(Float64, numSamples)))
img[:,j,i] = [cl.x, cl.y, cl.z]
end
end
img
end
#the scene
p1 = xzRect(1.,0.,1.,-1.,0.,Vec3(0,-1,0),Vec3(0,0,0),Vec3(0.75,0.75,0.75),false)
p2 = xzRect(0.,0.,1.,-1.,0.,Vec3(0,1,0),Vec3(0,0,0),Vec3(0.75,0.75,0.75),false)
p3 = xyRect(-1.,0.,1.,0.,1.,Vec3(0,0,1),Vec3(0,0,0),Vec3(0.75,0.75,0.75),false)
p4 = yzRect(0.,0.,1.,-1.,0.,Vec3(1,0,0),Vec3(0,0,0),Vec3(0.75,0.25,0.25),false)
p5 = yzRect(1.,0.,1.,-1.,0.,Vec3(-1,0,0),Vec3(0,0,0),Vec3(0.25,0.25,0.75),false)
p6 = xzRect(0.999,0.35,0.65,-0.65,-0.35,Vec3(0,-1,0),Vec3(18,18,18),Vec3(0,0,0),true)
s1 = Sphere(0.15,Vec3(0.3,0.15,-0.6),Vec3(0,0,0),Vec3(0,0,0),Vec3(0.75,0.75,0.75),false)
surfs = Surfaces[p1,p2,p3,p4,p5,p6,s1]
cam = Camera(Vec3(0.5,0.5,2),Vec3(0,1,0),Vec3(0,0,1),28.07,1,2)
#time image = render(surfs, cam, 400, 400, 1, 4);
colorview(RGB, image)
I need to know why my code is bad and slow. I am a beginner programmer and I don't have enough experience. My path tracer scene contains 7 objects, its maximum depth is 4, and it takes more than 2 seconds to generate an image of size 400*400. I think It shouldn't be that slow because my cpu is core i7 4770.
Sorry for changing my post.
To start with,
struct yzRect
x; y1; y2; z1; z2::Float64
normal; emittance; reflectance::Vec3
isLight::Bool
end
ends up only applying the type to the last variable for each line:
julia> fieldtypes(yzRect)
(Any, Any, Any, Any, Float64, Any, Any, Vec3, Bool)
so Julia will basically not know about any types in your structs which slows things down.
Also, your Vec3 should really be immutable and you then just create new instances of it when you want to "modify" the Vector.
There might be many more issues but those are two standing out.
Reading through https://docs.julialang.org/en/v1/manual/performance-tips/index.html and applying the guidelines in there is strongly recommended when analyzing performance.
I must be missing something really simple here. I've got some JS code that creates simple linear systems (I'm trying to create the shortest line between two skew lines). I've gotten to the point where I have Ax = b, and need to solve for x. A is a 3 x 2 matrix, b is 3 x 1.
I have:
function build_equation_system(v1, v2, b) {
var a = [ [v1.x, v2.x], [v1.y, v2.y], [v1.z, v2.z] ];
var b = [ [b.x], [b.y], [b.z]];
return numeric.solve(a,b)
}
Numeric returns a 1 x 3 matrix of NaNs, even when there is a solution.
Using numeric you can do the following:
Create a function which computes the pseudoinverse of your A matrix:
function pinv(A) {
return numeric.dot(numeric.inv(numeric.dot(numeric.transpose(A),A)),numeric.transpose(A));
}
Use that function to solve your linear least squares equation to get the coefficients.
var p = numeric.dot(pinv(a),b);
I tried your initial method of using numeric.solve and could not get it to work either so I'd be interested to know what the problem is.
A simple test...
var x = new Array(10);
var y = new Array(10);
for (var i = 0; i < 10; ++i) {
x[i] = i;
y[i] = i;
}
// Solve for the first order equation representing this data
var n = 1;
// Construct Vandermonde matrix.
var A = numeric.rep([x.length, n + 1], 1);
for (var i = 0; i < x.length; ++i) {
for (var j = n-1; j >= 0; --j) {
A[i][j] = x[i] * A[i][j+1];
}
}
// Solves the system Ap = y
var p = numeric.dot(pinv(A),y);
p = [1, 2.55351295663786e-15]
I've used this method to recreate MATLAB's polyfit for Javascript use.
As we all know, the simplest algorithm to generate Fibonacci sequence is as follows:
if(n<=0) return 0;
else if(n==1) return 1;
f(n) = f(n-1) + f(n-2);
But this algorithm has some repetitive calculation. For example, if you calculate f(5), it will calculate f(4) and f(3). When you calculate f(4), it will again calculate both f(3) and f(2). Could someone give me a more time-efficient recursive algorithm?
I have read about some of the methods for calculating Fibonacci with efficient time complexity following are some of them -
Method 1 - Dynamic Programming
Now here the substructure is commonly known hence I'll straightly Jump to the solution -
static int fib(int n)
{
int f[] = new int[n+2]; // 1 extra to handle case, n = 0
int i;
f[0] = 0;
f[1] = 1;
for (i = 2; i <= n; i++)
{
f[i] = f[i-1] + f[i-2];
}
return f[n];
}
A space-optimized version of above can be done as follows -
static int fib(int n)
{
int a = 0, b = 1, c;
if (n == 0)
return a;
for (int i = 2; i <= n; i++)
{
c = a + b;
a = b;
b = c;
}
return b;
}
Method 2- ( Using power of the matrix {{1,1},{1,0}} )
This an O(n) which relies on the fact that if we n times multiply the matrix M = {{1,1},{1,0}} to itself (in other words calculate power(M, n )), then we get the (n+1)th Fibonacci number as the element at row and column (0, 0) in the resultant matrix. This solution would have O(n) time.
The matrix representation gives the following closed expression for the Fibonacci numbers:
fibonaccimatrix
static int fib(int n)
{
int F[][] = new int[][]{{1,1},{1,0}};
if (n == 0)
return 0;
power(F, n-1);
return F[0][0];
}
/*multiplies 2 matrices F and M of size 2*2, and
puts the multiplication result back to F[][] */
static void multiply(int F[][], int M[][])
{
int x = F[0][0]*M[0][0] + F[0][1]*M[1][0];
int y = F[0][0]*M[0][1] + F[0][1]*M[1][1];
int z = F[1][0]*M[0][0] + F[1][1]*M[1][0];
int w = F[1][0]*M[0][1] + F[1][1]*M[1][1];
F[0][0] = x;
F[0][1] = y;
F[1][0] = z;
F[1][1] = w;
}
/*function that calculates F[][] raise to the power n and puts the
result in F[][]*/
static void power(int F[][], int n)
{
int i;
int M[][] = new int[][]{{1,1},{1,0}};
// n - 1 times multiply the matrix to {{1,0},{0,1}}
for (i = 2; i <= n; i++)
multiply(F, M);
}
This can be optimized to work in O(Logn) time complexity. We can do recursive multiplication to get power(M, n) in the previous method.
static int fib(int n)
{
int F[][] = new int[][]{{1,1},{1,0}};
if (n == 0)
return 0;
power(F, n-1);
return F[0][0];
}
static void multiply(int F[][], int M[][])
{
int x = F[0][0]*M[0][0] + F[0][1]*M[1][0];
int y = F[0][0]*M[0][1] + F[0][1]*M[1][1];
int z = F[1][0]*M[0][0] + F[1][1]*M[1][0];
int w = F[1][0]*M[0][1] + F[1][1]*M[1][1];
F[0][0] = x;
F[0][1] = y;
F[1][0] = z;
F[1][1] = w;
}
static void power(int F[][], int n)
{
if( n == 0 || n == 1)
return;
int M[][] = new int[][]{{1,1},{1,0}};
power(F, n/2);
multiply(F, F);
if (n%2 != 0)
multiply(F, M);
}
Method 3 (O(log n) Time)
Below is one more interesting recurrence formula that can be used to find nth Fibonacci Number in O(log n) time.
If n is even then k = n/2:
F(n) = [2*F(k-1) + F(k)]*F(k)
If n is odd then k = (n + 1)/2
F(n) = F(k)*F(k) + F(k-1)*F(k-1)
How does this formula work?
The formula can be derived from the above matrix equation.
fibonaccimatrix
Taking determinant on both sides, we get
(-1)n = Fn+1Fn-1 – Fn2
Moreover, since AnAm = An+m for any square matrix A, the following identities can be derived (they are obtained from two different coefficients of the matrix product)
FmFn + Fm-1Fn-1 = Fm+n-1
By putting n = n+1,
FmFn+1 + Fm-1Fn = Fm+n
Putting m = n
F2n-1 = Fn2 + Fn-12
F2n = (Fn-1 + Fn+1)Fn = (2Fn-1 + Fn)Fn (Source: Wiki)
To get the formula to be proved, we simply need to do the following
If n is even, we can put k = n/2
If n is odd, we can put k = (n+1)/2
public static int fib(int n)
{
if (n == 0)
return 0;
if (n == 1 || n == 2)
return (f[n] = 1);
// If fib(n) is already computed
if (f[n] != 0)
return f[n];
int k = (n & 1) == 1? (n + 1) / 2
: n / 2;
// Applyting above formula [See value
// n&1 is 1 if n is odd, else 0.
f[n] = (n & 1) == 1? (fib(k) * fib(k) +
fib(k - 1) * fib(k - 1))
: (2 * fib(k - 1) + fib(k))
* fib(k);
return f[n];
}
Method 4 - Using a formula
In this method, we directly implement the formula for the nth term in the Fibonacci series. Time O(1) Space O(1)
Fn = {[(√5 + 1)/2] ^ n} / √5
static int fib(int n) {
double phi = (1 + Math.sqrt(5)) / 2;
return (int) Math.round(Math.pow(phi, n)
/ Math.sqrt(5));
}
Reference: http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/fibFormula.html
Look here for implementation in Erlang which uses formula
. It shows nice linear resulting behavior because in O(M(n) log n) part M(n) is exponential for big numbers. It calculates fib of one million in 2s where result has 208988 digits. The trick is that you can compute exponentiation in O(log n) multiplications using (tail) recursive formula (tail means with O(1) space when used proper compiler or rewrite to cycle):
% compute X^N
power(X, N) when is_integer(N), N >= 0 ->
power(N, X, 1).
power(0, _, Acc) ->
Acc;
power(N, X, Acc) ->
if N rem 2 =:= 1 ->
power(N - 1, X, Acc * X);
true ->
power(N div 2, X * X, Acc)
end.
where X and Acc you substitute with matrices. X will be initiated with and Acc with identity I equals to .
One simple way is to calculate it iteratively instead of recursively. This will calculate F(n) in linear time.
def fib(n):
a,b = 0,1
for i in range(n):
a,b = a+b,a
return a
Hint: One way you achieve faster results is by using Binet's formula:
Here is a way of doing it in Python:
from decimal import *
def fib(n):
return int((Decimal(1.6180339)**Decimal(n)-Decimal(-0.6180339)**Decimal(n))/Decimal(2.236067977))
you can save your results and use them :
public static long[] fibs;
public long fib(int n) {
fibs = new long[n];
return internalFib(n);
}
public long internalFib(int n) {
if (n<=2) return 1;
fibs[n-1] = fibs[n-1]==0 ? internalFib(n-1) : fibs[n-1];
fibs[n-2] = fibs[n-2]==0 ? internalFib(n-2) : fibs[n-2];
return fibs[n-1]+fibs[n-2];
}
F(n) = (φ^n)/√5 and round to nearest integer, where φ is the golden ratio....
φ^n can be calculated in O(lg(n)) time hence F(n) can be calculated in O(lg(n)) time.
// D Programming Language
void vFibonacci ( const ulong X, const ulong Y, const int Limit ) {
// Equivalent : if ( Limit != 10 ). Former ( Limit ^ 0xA ) is More Efficient However.
if ( Limit ^ 0xA ) {
write ( Y, " " ) ;
vFibonacci ( Y, Y + X, Limit + 1 ) ;
} ;
} ;
// Call As
// By Default the Limit is 10 Numbers
vFibonacci ( 0, 1, 0 ) ;
EDIT: I actually think Hynek Vychodil's answer is superior to mine, but I'm leaving this here just in case someone is looking for an alternate method.
I think the other methods are all valid, but not optimal. Using Binet's formula should give you the right answer in principle, but rounding to the closest integer will give some problems for large values of n. The other solutions will unnecessarily recalculate the values upto n every time you call the function, and so the function is not optimized for repeated calling.
In my opinion the best thing to do is to define a global array and then to add new values to the array IF needed. In Python:
import numpy
fibo=numpy.array([1,1])
last_index=fibo.size
def fib(n):
global fibo,last_index
if (n>0):
if(n>last_index):
for i in range(last_index+1,n+1):
fibo=numpy.concatenate((fibo,numpy.array([fibo[i-2]+fibo[i-3]])))
last_index=fibo.size
return fibo[n-1]
else:
print "fib called for index less than 1"
quit()
Naturally, if you need to call fib for n>80 (approximately) then you will need to implement arbitrary precision integers, which is easy to do in python.
This will execute faster, O(n)
def fibo(n):
a, b = 0, 1
for i in range(n):
if i == 0:
print(i)
elif i == 1:
print(i)
else:
temp = a
a = b
b += temp
print(b)
n = int(input())
fibo(n)