forked from M-Labs/nalgebra
Added valid method
This commit is contained in:
parent
4f9a3cf1e6
commit
fd0c497c90
@ -6,57 +6,120 @@ use std::cmp;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// evum CovvolveMode{
|
enum ConvolveMode{
|
||||||
// Full,
|
Full,
|
||||||
// Valid,
|
Valid,
|
||||||
// Same
|
Same
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
fn Convolve1D<R: Real, D: Dim, E: Dim, S: Storage<R, D>, Q: Storage<R, E>>(
|
|
||||||
Vector : Vector<R,D,S>,
|
|
||||||
Kernel : Vector<R,E,Q>
|
|
||||||
) -> Matrix<R, Dynamic, U1, VecStorage<R, Dynamic, U1>>
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Vector is the vector, Kervel is the kervel
|
|
||||||
// C is the returv vector
|
|
||||||
//
|
|
||||||
if Kernel.len() > Vector.len(){
|
|
||||||
return Convolve1D(Kernel, Vector);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let V = Vector.len();
|
fn convolve_full<R: Real, D: Dim, E: Dim, S: Storage<R, D>, Q: Storage<R, E>>(
|
||||||
let K = Kernel.len();
|
vector : Vector<R,D,S>,
|
||||||
let L = V + K - 1;
|
kernel : Vector<R,E,Q>
|
||||||
let v = V as i8;
|
) -> Matrix<R, Dynamic, U1, VecStorage<R, Dynamic, U1>>
|
||||||
let k = K as i8;
|
{
|
||||||
let l = L as i8;
|
|
||||||
let mut C = DVector::<R>::zeros(L);
|
let vec = vector.len();
|
||||||
|
let ker = kernel.len();
|
||||||
|
let len = vec + ker - 1;
|
||||||
|
let v = vec as i8;
|
||||||
|
let k = ker as i8;
|
||||||
|
let l = len as i8;
|
||||||
|
let mut conv = DVector::<R>::zeros(len);
|
||||||
|
|
||||||
for i in 0..l{
|
for i in 0..l{
|
||||||
let u_i = cmp::max(0, i - k);
|
let u_i = cmp::max(0, i - k);
|
||||||
let u_f = cmp::min(i, v - 1);
|
let u_f = cmp::min(i, v - 1);
|
||||||
|
|
||||||
if u_i == u_f{
|
if u_i == u_f{
|
||||||
C[i as usize] += Vector[u_i as usize] * Kernel[(i - u_i) as usize];
|
conv[i as usize] += vector[u_i as usize] * kernel[(i - u_i) as usize];
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
for u in u_i..(u_f+1){
|
for u in u_i..(u_f+1){
|
||||||
if i - u < k{
|
if i - u < k{
|
||||||
C[i as usize] += Vector[u as usize] * Kernel[(i - u ) as usize];
|
conv[i as usize] += vector[u as usize] * kernel[(i - u ) as usize];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
C
|
conv
|
||||||
|
}
|
||||||
|
|
||||||
|
fn convolve_valid<R: Real, D: Dim, E: Dim, S: Storage<R, D>, Q: Storage<R, E>>(
|
||||||
|
vector : Vector<R,D,S>,
|
||||||
|
kernel : Vector<R,E,Q>
|
||||||
|
) -> Matrix<R, Dynamic, U1, VecStorage<R, Dynamic, U1>>
|
||||||
|
{
|
||||||
|
let vec = vector.len();
|
||||||
|
let ker = kernel.len();
|
||||||
|
let len = vec - ker + 1;
|
||||||
|
let mut conv = DVector::<R>::zeros(len);
|
||||||
|
|
||||||
|
for i in 0..len {
|
||||||
|
for j in 0..ker {
|
||||||
|
conv[i] += vector[i + j] * kernel[ker - j - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
conv
|
||||||
|
}
|
||||||
|
|
||||||
|
fn convolve_same<R: Real, D: Dim, E: Dim, S: Storage<R, D>, Q: Storage<R, E>>(
|
||||||
|
vector : Vector<R,D,S>,
|
||||||
|
kernel : Vector<R,E,Q>
|
||||||
|
) -> Matrix<R, Dynamic, U1, VecStorage<R, Dynamic, U1>>
|
||||||
|
{
|
||||||
|
|
||||||
|
let vec = vector.len();
|
||||||
|
let ker = kernel.len();
|
||||||
|
let len = vec + ker - 1;
|
||||||
|
let v = vec as i8;
|
||||||
|
let k = ker as i8;
|
||||||
|
let l = len as i8;
|
||||||
|
let mut conv = DVector::<R>::zeros(len);
|
||||||
|
|
||||||
|
for i in 0..l {
|
||||||
|
let u_i = cmp::max(0, i - k);
|
||||||
|
let u_f = cmp::min(i, v - 1);
|
||||||
|
|
||||||
|
if u_i == u_f {
|
||||||
|
conv[i as usize] += vector[u_i as usize] * kernel[(i - u_i) as usize];
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
for u in u_i..(u_f+1){
|
||||||
|
if i - u < k{
|
||||||
|
conv[i as usize] += vector[u as usize] * kernel[(i - u ) as usize];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
conv
|
||||||
|
}
|
||||||
|
|
||||||
|
fn convolve<R: Real, D: Dim, E: Dim, S: Storage<R, D>, Q: Storage<R, E>>(
|
||||||
|
vector : Vector<R,D,S>,
|
||||||
|
kernel : Vector<R,E,Q>,
|
||||||
|
mode : Option<ConvolveMode>
|
||||||
|
) -> Matrix<R, Dynamic, U1, VecStorage<R, Dynamic, U1>>
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// vector is the vector, Kervel is the kervel
|
||||||
|
// C is the returv vector
|
||||||
|
//
|
||||||
|
if kernel.len() > vector.len(){
|
||||||
|
return convolve(kernel, vector, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
match mode.unwrap_or(ConvolveMode::Full) {
|
||||||
|
ConvolveMode::Full => return convolve_full(vector,kernel),
|
||||||
|
ConvolveMode::Valid => return convolve_valid(vector,kernel),
|
||||||
|
ConvolveMode::Same => return convolve_same(vector,kernel)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let v1 = Vector2::new(3.0,3.0);
|
let v1 = Vector2::new(3.0,1.0);
|
||||||
let v2 = Vector4::new(1.0,2.0,5.0,9.0);
|
let v2 = Vector4::new(1.0,2.0,5.0,9.0);
|
||||||
let x = Convolve1D(v1,v2);
|
let x = convolve(v1,v2,Some(ConvolveMode::Valid));
|
||||||
println!("{:?}",x)
|
println!("{:?}",x)
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user