Solving linear equation with LAPACKE - c

I'm trying to solve some linear equation (which is symmetrical, tridiagonal and positive). I have to use LAPACKE. My code is as follows:
#include <lapacke.h>
#include <stdio.h>
void print_mtrx(double * mtrx, int n, int m)
{
int i, j;
for(i = 0; i < n; i++)
{
for(j = 0; j < m; j++)
{
printf("%f ", mtrx[i*m+j]);
}
printf("\n");
}
printf("\n");
}
int main()
{
double matrix[5*5] = {
2, 0, 0, 0, 0,
0, 2, 0, 0, 0,
0, 0, 2, 0, 0,
0, 0, 0, 2, 0,
0, 0, 0, 0, 2
};
double rozw[5] = {1,2,3,4,5};
double matrix2[5*5] = {
7, 0, 0, 0, 0,
0, 7, 0, 0, 0,
0, 0, 7, 0, 0,
0, 0, 0, 7, 0,
0, 0, 0, 0, 7
};
LAPACKE_dptsv(LAPACK_COL_MAJOR, 5, 5, matrix, matrix2, rozw, 5);
print_mtrx(matrix, 5, 5);
print_mtrx(matrix2, 5, 5);
print_mtrx(rozw, 5, 1);
}
LAPACKE's function seems to do nothing, without any errors. The main problem is, I have no idea what do the function parameters stand for. I've searched long, but there is no real documentation. Here is what I managed to found or guess:
int matrix_order -- LAPACK_COL_MAJOR or LAPACK_ROW_MAJOR, how is matrix represented in memory
lapack_int n -- size of matrix (i.e. number of columns)
lapack_int nrhs -- not sure, maybe size of vector b
double* d -- matrix of equations
double* e -- no idea.
double* b -- vector of solutions of equations from d
lapack_int ldb -- leading direction of b (wherefore? is it not identical to nrhs, which itself is identical to n?)
How can I find real meaning of these arguments? How can I make my code work?

So one must to look into documentation of pure LAPACK (http://www.netlib.org/lapack/explore-html/d0/dea/dptsv_8f.html#af1bd4c731915bd8755a4da8086fd79a8), and also ignore incorrect (in case of LAPACKE) remark that LDB be greater or equal max(1,N).
The correct program is as follows:
#include <lapacke.h>
#include <stdio.h>
void print_mtrx(double * mtrx, int n, int m)
{
int i, j;
for(i = 0; i < n; i++)
{
for(j = 0; j < m; j++)
{
printf("%f ", mtrx[i*m+j]);
}
printf("\n");
}
printf("\n");
}
int main()
{
double diagonal[5] = {5,1,5,1,5};
double subdiagonal[4] = {0,0,0,0};
double solution[5] = {1,2,3,4,5};
LAPACKE_dptsv(LAPACK_ROW_MAJOR, 5 /*size of matrix*/, 1 /*number of columns in solution*/,
diagonal, subdiagonal, solution, 1 /*leading dimension of solution vector*/);
print_mtrx(solution, 5, 1);
}

When it comes to documentation for BLAS and/or LAPACK, Intel is probably the most comprehensive out there. You can look up the docs for ?ptsv, which explains what each parameter is for.
(Hint: when searching for a BLAS or LAPACK in Google, be sure to drop the s/d/c/z prefix.)
Here's the relevant snippet:
The routine solves for X the real or complex system of linear equations A*X = B, where A is an n-by-n symmetric/Hermitian positive-definite tridiagonal matrix, the columns of matrix B are individual right-hand sides, and the columns of X are the corresponding solutions.
A is factored as A = L*D*LT (real flavors) or A = L*D*LH (complex flavors), and the factored form of A is then used to solve the system of equations A*X = B.
Input Parameters
n: The order of matrix A; n ≥ 0.
nrhs: The number of right-hand sides, the number of columns in B; nrhs ≥ 0.
d: Array, dimension at least max(1, n). Contains the diagonal elements of the tridiagonal matrix A.
e, b: Arrays: e(n - 1), b(ldb,*). The array e contains the (n - 1) subdiagonal elements of A. The array b contains the matrix B whose columns are the right-hand sides for the systems of equations. The second dimension of b must be at least max(1,nrhs).
ldb: The leading dimension of b; ldb ≥ max(1, n).
Output Parameters
d: Overwritten by the n diagonal elements of the diagonal matrix D from the L*D*LT (real) / L*D*LH (complex) factorization of A.
e: Overwritten by the (n - 1) subdiagonal elements of the unit bidiagonal factor L from the factorization of A.
b: Overwritten by the solution matrix X.
info: If info = 0, the execution is successful. If info = -i, the i-th parameter had an illegal value. If info = i, the leading minor of order i (and therefore the matrix A itself) is not positive-definite, and the solution has not been computed. The factorization has not been completed unless i = n.

Related

Closest pairs of elements in two sorted arrays

We are looking for an efficient algorithm to solve the following problem:
Given two increasingly sorted arrays.
Find the closest corresponding elements in each array that difference is
below a user given threshold. But only the closest of possible candidates
(in the range of array1[i] +/- threshold) should be returned.
The second closest could be matched to another element but
matches to more than one element are not allowed. If two elements in
array1 have the same distance to array2[j] the first (leftmost) match
should be reported.
The arrays can contain duplicated values. There the first (leftmost) match
should be reported (and all the others ignored/not matched).
Examples:
x: 1, 3, 5, 6, 8
y: 3, 4, 5, 7
threshold: 1
output: NA, 1, 3, 4, NA
(index of y that matches best to x)
x: 1, 1.5, 2, 2.1, 5, 6.1, 7.2
y: 4.6, 4.7, 4.8, 4.9, 5, 6, 7, 8
threshold: 3
output: NA, NA, NA, 1, 5, 6, 7
(index of y that matches best to x)
x: 1, 1, 1, 2, 2, 2
y: 1, 2
threshold: 0
output: 1, NA, NA, 2, NA, NA
(index of y that matches best to x, for duplicates choose to first one)
x: 1, 2
y: 1, 1, 1, 2, 2, 2
threshold: 0
output: 1, 4
(index of y that matches best to x, for duplicates choose to first one)
We use this to find the closest matching values between two m/z-values
(mass-to-charge ratios) while comparing mass spectra.
Currently we iterate through both arrays and lookahead the differences for the
next two elements and correct the previous element if a closer one was found.
But this fails for more than two duplicate elements in a row (second example):
Our current implementation (C code as part of an R package):
https://github.com/rformassspectrometry/MsCoreUtils/blob/master/src/closest.c#L73-L129
A commented version below:
SEXP C_closest_dup_closest(SEXP x, SEXP table, SEXP tolerance, SEXP nomatch) {
/* x is the first array of doubles */
double *px = REAL(x);
const unsigned int nx = LENGTH(x);
/* table is the second array of doubles where x should be matched against */
double *ptable = REAL(table);
const unsigned int ntable = LENGTH(table);
/* user given tolerance threshold */
double *ptolerance = REAL(tolerance);
/* integer array to store the results */
SEXP out = PROTECT(allocVector(INTSXP, nx));
int* pout = INTEGER(out);
/* integer that should returned if no valid match or a closer one was found */
const unsigned int inomatch = asInteger(nomatch);
/* indices */
unsigned int ix = 0, ixlastused = 1;
unsigned int itbl = 0, itbllastused = 1;
/* differences: current, difference to next element of x and table, respectively */
double diff = R_PosInf, diffnxtx = R_PosInf, diffnxttbl = R_PosInf;
while (ix < nx) {
if (itbl < ntable) {
/* difference for current pair */
diff = fabs(px[ix] - ptable[itbl]);
/* difference for next pairs */
diffnxtx =
ix + 1 < nx ? fabs(px[ix + 1] - ptable[itbl]) : R_PosInf;
diffnxttbl =
itbl + 1 < ntable ? fabs(px[ix] - ptable[itbl + 1]) : R_PosInf;
if (diff <= ptolerance[ix]) {
/* valid match, add + 1 to convert between R/C index */
pout[ix] = itbl + 1;
if (itbl == itbllastused &&
(diffnxtx < diffnxttbl || diff < diffnxttbl))
pout[ixlastused] = inomatch;
ixlastused = ix;
itbllastused = itbl;
} else
pout[ix] = inomatch;
if (diffnxtx < diff || diffnxttbl < diff) {
/* increment the index with the smaller distance */
if (diffnxtx < diffnxttbl)
++ix;
else
++itbl;
} else {
/* neither next x nor next table item offer a better match */
++ix;
++itbl;
}
} else
pout[ix++] = inomatch;
}
/* R provided MACRO to free allocated memory */
UNPROTECT(1);
return out;
}
Could anybody give us a hint for a better algorithm?

Finding an algorithm for indexing all combinations [duplicate]

Given an array of N elements representing the permutation atoms, is there an algorithm like that:
function getNthPermutation( $atoms, $permutation_index, $size )
where $atoms is the array of elements, $permutation_index is the index of the permutation and $size is the size of the permutation.
For instance:
$atoms = array( 'A', 'B', 'C' );
// getting third permutation of 2 elements
$perm = getNthPermutation( $atoms, 3, 2 );
echo implode( ', ', $perm )."\n";
Would print:
B, A
Without computing every permutation until $permutation_index ?
I heard something about factoradic permutations, but every implementation i've found gives as result a permutation with the same size of V, which is not my case.
Thanks.
As stated by RickyBobby, when considering the lexicographical order of permutations, you should use the factorial decomposition at your advantage.
From a practical point of view, this is how I see it:
Perform a sort of Euclidian division, except you do it with factorial numbers, starting with (n-1)!, (n-2)!, and so on.
Keep the quotients in an array. The i-th quotient should be a number between 0 and n-i-1 inclusive, where i goes from 0 to n-1.
This array is your permutation. The problem is that each quotient does not care for previous values, so you need to adjust them. More explicitly, you need to increment every value as many times as there are previous values that are lower or equal.
The following C code should give you an idea of how this works (n is the number of entries, and i is the index of the permutation):
/**
* #param n The number of entries
* #param i The index of the permutation
*/
void ithPermutation(const int n, int i)
{
int j, k = 0;
int *fact = (int *)calloc(n, sizeof(int));
int *perm = (int *)calloc(n, sizeof(int));
// compute factorial numbers
fact[k] = 1;
while (++k < n)
fact[k] = fact[k - 1] * k;
// compute factorial code
for (k = 0; k < n; ++k)
{
perm[k] = i / fact[n - 1 - k];
i = i % fact[n - 1 - k];
}
// readjust values to obtain the permutation
// start from the end and check if preceding values are lower
for (k = n - 1; k > 0; --k)
for (j = k - 1; j >= 0; --j)
if (perm[j] <= perm[k])
perm[k]++;
// print permutation
for (k = 0; k < n; ++k)
printf("%d ", perm[k]);
printf("\n");
free(fact);
free(perm);
}
For example, ithPermutation(10, 3628799) prints, as expected, the last permutation of ten elements:
9 8 7 6 5 4 3 2 1 0
Here's a solution that allows to select the size of the permutation. For example, apart from being able to generate all permutations of 10 elements, it can generate permutations of pairs among 10 elements. Also it permutes lists of arbitrary objects, not just integers.
function nth_permutation($atoms, $index, $size) {
for ($i = 0; $i < $size; $i++) {
$item = $index % count($atoms);
$index = floor($index / count($atoms));
$result[] = $atoms[$item];
array_splice($atoms, $item, 1);
}
return $result;
}
Usage example:
for ($i = 0; $i < 6; $i++) {
print_r(nth_permutation(['A', 'B', 'C'], $i, 2));
}
// => AB, BA, CA, AC, BC, CB
How does it work?
There's a very interesting idea behind it. Let's take the list A, B, C, D. We can construct a permutation by drawing elements from it like from a deck of cards. Initially we can draw one of the four elements. Then one of the three remaining elements, and so on, until finally we have nothing left.
Here is one possible sequence of choices. Starting from the top we're taking the third path, then the first, the the second, and finally the first. And that's our permutation #13.
Think about how, given this sequence of choices, you would get to the number thirteen algorithmically. Then reverse your algorithm, and that's how you can reconstruct the sequence from an integer.
Let's try to find a general scheme for packing a sequence of choices into an integer without redundancy, and unpacking it back.
One interesting scheme is called decimal number system. "27" can be thought of as choosing path #2 out of 10, and then choosing path #7 out of 10.
But each digit can only encode choices from 10 alternatives. Other systems that have a fixed radix, like binary and hexadecimal, also can only encode sequences of choices from a fixed number of alternatives. We want a system with a variable radix, kind of like time units, "14:05:29" is hour 14 from 24, minute 5 from 60, second 29 from 60.
What if we take generic number-to-string and string-to-number functions, and fool them into using mixed radixes? Instead of taking a single radix, like parseInt('beef', 16) and (48879).toString(16), they will take one radix per each digit.
function pack(digits, radixes) {
var n = 0;
for (var i = 0; i < digits.length; i++) {
n = n * radixes[i] + digits[i];
}
return n;
}
function unpack(n, radixes) {
var digits = [];
for (var i = radixes.length - 1; i >= 0; i--) {
digits.unshift(n % radixes[i]);
n = Math.floor(n / radixes[i]);
}
return digits;
}
Does that even work?
// Decimal system
pack([4, 2], [10, 10]); // => 42
// Binary system
pack([1, 0, 1, 0, 1, 0], [2, 2, 2, 2, 2, 2]); // => 42
// Factorial system
pack([1, 3, 0, 0, 0], [5, 4, 3, 2, 1]); // => 42
And now backwards:
unpack(42, [10, 10]); // => [4, 2]
unpack(42, [5, 4, 3, 2, 1]); // => [1, 3, 0, 0, 0]
This is so beautiful. Now let's apply this parametric number system to the problem of permutations. We'll consider length 2 permutations of A, B, C, D. What's the total number of them? Let's see: first we draw one of the 4 items, then one of the remaining 3, that's 4 * 3 = 12 ways to draw 2 items. These 12 ways can be packed into integers [0..11]. So, let's pretend we've packed them already, and try unpacking:
for (var i = 0; i < 12; i++) {
console.log(unpack(i, [4, 3]));
}
// [0, 0], [0, 1], [0, 2],
// [1, 0], [1, 1], [1, 2],
// [2, 0], [2, 1], [2, 2],
// [3, 0], [3, 1], [3, 2]
These numbers represent choices, not indexes in the original array. [0, 0] doesn't mean taking A, A, it means taking item #0 from A, B, C, D (that's A) and then item #0 from the remaining list B, C, D (that's B). And the resulting permutation is A, B.
Another example: [3, 2] means taking item #3 from A, B, C, D (that's D) and then item #2 from the remaining list A, B, C (that's C). And the resulting permutation is D, C.
This mapping is called Lehmer code. Let's map all these Lehmer codes to permutations:
AB, AC, AD, BA, BC, BD, CA, CB, CD, DA, DB, DC
That's exactly what we need. But if you look at the unpack function you'll notice that it produces digits from right to left (to reverse the actions of pack). The choice from 3 gets unpacked before the choice from 4. That's unfortunate, because we want to choose from 4 elements before choosing from 3. Without being able to do so we have to compute the Lehmer code first, accumulate it into a temporary array, and then apply it to the array of items to compute the actual permutation.
But if we don't care about the lexicographic order, we can pretend that we want to choose from 3 elements before choosing from 4. Then the choice from 4 will come out from unpack first. In other words, we'll use unpack(n, [3, 4]) instead of unpack(n, [4, 3]). This trick allows to compute the next digit of Lehmer code and immediately apply it to the list. And that's exactly how nth_permutation() works.
One last thing I want to mention is that unpack(i, [4, 3]) is closely related to the factorial number system. Look at that first tree again, if we want permutations of length 2 without duplicates, we can just skip every second permutation index. That'll give us 12 permutations of length 4, which can be trimmed to length 2.
for (var i = 0; i < 12; i++) {
var lehmer = unpack(i * 2, [4, 3, 2, 1]); // Factorial number system
console.log(lehmer.slice(0, 2));
}
It depends on the way you "sort" your permutations (lexicographic order for example).
One way to do it is the factorial number system, it gives you a bijection between [0 , n!] and all the permutations.
Then for any number i in [0,n!] you can compute the ith permutation without computing the others.
This factorial writing is based on the fact that any number between [ 0 and n!] can be written as :
SUM( ai.(i!) for i in range [0,n-1]) where ai <i
(it's pretty similar to base decomposition)
for more information on this decomposition, have a look at this thread : https://math.stackexchange.com/questions/53262/factorial-decomposition-of-integers
hope it helps
As stated on this wikipedia article this approach is equivalent to computing the lehmer code :
An obvious way to generate permutations of n is to generate values for
the Lehmer code (possibly using the factorial number system
representation of integers up to n!), and convert those into the
corresponding permutations. However the latter step, while
straightforward, is hard to implement efficiently, because it requires
n operations each of selection from a sequence and deletion from it,
at an arbitrary position; of the obvious representations of the
sequence as an array or a linked list, both require (for different
reasons) about n2/4 operations to perform the conversion. With n
likely to be rather small (especially if generation of all
permutations is needed) that is not too much of a problem, but it
turns out that both for random and for systematic generation there are
simple alternatives that do considerably better. For this reason it
does not seem useful, although certainly possible, to employ a special
data structure that would allow performing the conversion from Lehmer
code to permutation in O(n log n) time.
So the best you can do for a set of n element is O(n ln(n)) with an adapted data structure.
Here's an algorithm to convert between permutations and ranks in linear time. However, the ranking it uses is not lexicographic. It's weird, but consistent. I'm going to give two functions, one that converts from a rank to a permutation, and one that does the inverse.
First, to unrank (go from rank to permutation)
Initialize:
n = length(permutation)
r = desired rank
p = identity permutation of n elements [0, 1, ..., n]
unrank(n, r, p)
if n > 0 then
swap(p[n-1], p[r mod n])
unrank(n-1, floor(r/n), p)
fi
end
Next, to rank:
Initialize:
p = input permutation
q = inverse input permutation (in linear time, q[p[i]] = i for 0 <= i < n)
n = length(p)
rank(n, p, q)
if n=1 then return 0 fi
s = p[n-1]
swap(p[n-1], p[q[n-1]])
swap(q[s], q[n-1])
return s + n * rank(n-1, p, q)
end
The running time of both of these is O(n).
There's a nice, readable paper explaining why this works: Ranking & Unranking Permutations in Linear Time, by Myrvold & Ruskey, Information Processing Letters Volume 79, Issue 6, 30 September 2001, Pages 281–284.
http://webhome.cs.uvic.ca/~ruskey/Publications/RankPerm/MyrvoldRuskey.pdf
Here is a short and very fast (linear in the number of elements) solution in python, working for any list of elements (the 13 first letters in the example below) :
from math import factorial
def nthPerm(n,elems):#with n from 0
if(len(elems) == 1):
return elems[0]
sizeGroup = factorial(len(elems)-1)
q,r = divmod(n,sizeGroup)
v = elems[q]
elems.remove(v)
return v + ", " + ithPerm(r,elems)
Examples :
letters = ['a','b','c','d','e','f','g','h','i','j','k','l','m']
ithPerm(0,letters[:]) #--> a, b, c, d, e, f, g, h, i, j, k, l, m
ithPerm(4,letters[:]) #--> a, b, c, d, e, f, g, h, i, j, m, k, l
ithPerm(3587542868,letters[:]) #--> h, f, l, i, c, k, a, e, g, m, d, b, j
Note: I give letters[:] (a copy of letters) and not letters because the function modifies its parameter elems (removes chosen element)
The following code computes the kth permutation for given n.
i.e n=3.
The various permutations are
123
132
213
231
312
321
If k=5, return 312.
In other words, it gives the kth lexicographical permutation.
public static String getPermutation(int n, int k) {
char temp[] = IntStream.range(1, n + 1).mapToObj(i -> "" + i).collect(Collectors.joining()).toCharArray();
return getPermutationUTIL(temp, k, 0);
}
private static String getPermutationUTIL(char temp[], int k, int start) {
if (k == 1)
return new String(temp);
int p = factorial(temp.length - start - 1);
int q = (int) Math.floor(k / p);
if (k % p == 0)
q = q - 1;
if (p <= k) {
char a = temp[start + q];
for (int j = start + q; j > start; j--)
temp[j] = temp[j - 1];
temp[start] = a;
}
return k - p >= 0 ? getPermutationUTIL(temp, k - (q * p), start + 1) : getPermutationUTIL(temp, k, start + 1);
}
private static void swap(char[] arr, int j, int i) {
char temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
private static int factorial(int n) {
return n == 0 ? 1 : (n * factorial(n - 1));
}
It is calculable. This is a C# code that does it for you.
using System;
using System.Collections.Generic;
namespace WpfPermutations
{
public class PermutationOuelletLexico3<T>
{
// ************************************************************************
private T[] _sortedValues;
private bool[] _valueUsed;
public readonly long MaxIndex; // long to support 20! or less
// ************************************************************************
public PermutationOuelletLexico3(T[] sortedValues)
{
if (sortedValues.Length <= 0)
{
throw new ArgumentException("sortedValues.Lenght should be greater than 0");
}
_sortedValues = sortedValues;
Result = new T[_sortedValues.Length];
_valueUsed = new bool[_sortedValues.Length];
MaxIndex = Factorial.GetFactorial(_sortedValues.Length);
}
// ************************************************************************
public T[] Result { get; private set; }
// ************************************************************************
/// <summary>
/// Return the permutation relative to the index received, according to
/// _sortedValues.
/// Sort Index is 0 based and should be less than MaxIndex. Otherwise you get an exception.
/// </summary>
/// <param name="sortIndex"></param>
/// <param name="result">Value is not used as inpu, only as output. Re-use buffer in order to save memory</param>
/// <returns></returns>
public void GetValuesForIndex(long sortIndex)
{
int size = _sortedValues.Length;
if (sortIndex < 0)
{
throw new ArgumentException("sortIndex should be greater or equal to 0.");
}
if (sortIndex >= MaxIndex)
{
throw new ArgumentException("sortIndex should be less than factorial(the lenght of items)");
}
for (int n = 0; n < _valueUsed.Length; n++)
{
_valueUsed[n] = false;
}
long factorielLower = MaxIndex;
for (int index = 0; index < size; index++)
{
long factorielBigger = factorielLower;
factorielLower = Factorial.GetFactorial(size - index - 1); // factorielBigger / inverseIndex;
int resultItemIndex = (int)(sortIndex % factorielBigger / factorielLower);
int correctedResultItemIndex = 0;
for(;;)
{
if (! _valueUsed[correctedResultItemIndex])
{
resultItemIndex--;
if (resultItemIndex < 0)
{
break;
}
}
correctedResultItemIndex++;
}
Result[index] = _sortedValues[correctedResultItemIndex];
_valueUsed[correctedResultItemIndex] = true;
}
}
// ************************************************************************
/// <summary>
/// Calc the index, relative to _sortedValues, of the permutation received
/// as argument. Returned index is 0 based.
/// </summary>
/// <param name="values"></param>
/// <returns></returns>
public long GetIndexOfValues(T[] values)
{
int size = _sortedValues.Length;
long valuesIndex = 0;
List<T> valuesLeft = new List<T>(_sortedValues);
for (int index = 0; index < size; index++)
{
long indexFactorial = Factorial.GetFactorial(size - 1 - index);
T value = values[index];
int indexCorrected = valuesLeft.IndexOf(value);
valuesIndex = valuesIndex + (indexCorrected * indexFactorial);
valuesLeft.Remove(value);
}
return valuesIndex;
}
// ************************************************************************
}
}
If you store all the permutations in memory, for example in an array, you should be able to bring them back out one at a time in O(1) time.
This does mean you have to store all the permutations, so if computing all permutations takes a prohibitively long time, or storing them takes a prohibitively large space then this may not be a solution.
My suggestion would be to try it anyway, and come back if it is too big/slow - there's no point looking for a "clever" solution if a naive one will do the job.

Bspline implementation not working as expected

I made this implementation of the BSPLINE curve. I Followed the usual definition presented in http://en.wikipedia.org/wiki/B-spline
t is the knot vector.
#include <stdio.h>
double N(int i, int k, double u, double t[])
{
if(k == 1)
{
if(u >= t[i] && u < t[i+1])
return 1.0e0;
else {
return 0.0e0;
}
}
return ((u - t[i])*N(i, k -1, u, t))/(t[i+k-1] - t[i]) + ((t[i+k] - u)*N(i+1, k-1, u, t))/(t[i+k] - t[i+1]);
}
double pu(double u, double x[], int n, int k, double t[])
{
int i;
double r = 0.0e0;
for(i = 0; i < n; i++)
{
r += x[i]*N(i, k, u, t);
}
return r;
}
int main()
{
double t[] = {0.0, 0.5, 1, 2, 3, 4, 4.5, 5}; //knot vector
double x[] = {-30.0, 25.0, 9.0, 20.0, 25.0, 31.0}, y[] = {-5.0, -10.0, 3.0, -10.0, -5.0, 25.0}; //the points
double u;
for(u = 0.0e0; u < 5.0; u+=0.01e0)
{
printf("%lf %lf\n", pu(u, x, 6, 2, t), pu(u, y, 6, 2, t));
}
return 0;
}
The problem is that when I plot the computed points I see that there is an unexpected behavior at the beginning and end of the curve.
For instance:
I can not understand why this happens, try changing the values of t, but it seems that is not it.
There are two implementations of bspline: uniform and standard. In uniform the first and the last control points are not interpolated and in the standard knot sequence both are interpolated. In uniform, you can have uniform knots usually 1,2,3,... For standard knot sequence if you have order k (degree k-1) you should have k zeros, k ones and fill in the middle with 1/(m-k+2) where m is the number of control points. For example, having 5 control points and order 3, knot sequences are 0, 0, 0, 0.25, 0.5, 0.75, 1, 1, 1.
In addition, using delta functions you can have a much better implementation rather than computing N function. Delta function benefits from the local support of bspline. I suggest you take a look at the course notes that I teach at the University of Calgary:
http://pages.cpsc.ucalgary.ca/~amahdavi/pmwiki-2.2.8/uploads/Site/notes1.pdf
Check page 40 algorithm 3.3.
Hopefully it's helpful.
In general: if you have n control points and you construct a bspline curve of degree k, your knot vector has n+k+1 knots. The domain of the curve (i.e. where the summation of the basis functions are =1) is given in the interval [t_k, ... t_n] (as far as my details are right).
In the loop, your parameter values range from 0.0 to 5.0. This should be t[k] = t[2] = 1.0 to t[n] = t[6] = 4.0.
The wiki examples do it the other way, as the knot vectors given there have multiple values (i.e. k-times) at the beginning and the end. So the shown spline curve starts/ends at the first/last control point. Your construction does not give this property.

Line fit from an array of 2d vectors

I have a problem in some C code, I assume it belonged here over the Mathematics exchange.
I have an array of changes in x and y position generated by a user dragging a mouse, how could I determine if a straight line was drawn or not.
I am currently using linear regression, is there a better(more efficient) way to do this?
EDIT:
Hough transformation attempt:
#define abSIZE 100
#define ARRAYSIZE 10
int A[abSIZE][abSIZE]; //points in the a-b plane
int dX[10] = {0, 10, 13, 8, 20, 18, 19, 22, 12, 23};
int dY[10] = {0, 2, 3, 1, -1, -2, 0, 0, 3, 1};
int absX[10]; //absolute positions
int absY[10];
int error = 0;
int sumx = 0, sumy = 0, i;
//Convert deltas to absolute positions
for (i = 0; i<10; i++) {
absX[i] = sumx+=dX[i];
absY[i] = sumy+=dY[i];
}
//initialise array to zero
int a, b, x, y;
for(a = -abSIZE/2; a < abSIZE/2; a++) {
for(b = -abSIZE/2; b< abSIZE/2; b++) {
A[a+abSIZE/2][b+abSIZE/2] = 0;
}
}
//Hough transform
int aMax = 0;
int bMax = 0;
int highest = 0;
for(i=0; i<10; i++) {
x = absX[i];
y = absX[i];
for(a = -abSIZE/2; a < abSIZE/2; a++) {
for(b = -abSIZE/2; b< abSIZE/2; b++) {
if (a*x + b == y) {
A[a+abSIZE/2][b+abSIZE/2] += 1;
if (A[a+abSIZE/2][b+abSIZE/2] > highest) {
highest++; //highest = A[a+abSIZE/2][b+abSIZE/2]
aMax = a;
bMax = b;
}
}
}
}
}
printf("Line is Y = %d*X + %d\n",aMax,bMax);
//Calculate MSE
int e;
for (i = 0; i < ARRAYSIZE; i++) {
e = absY[i] - (aMax * absX[i] + bMax);
e = (int) pow((double)e, 2);
error += e;
}
printf("error is: %d\n", error);
Though linear regression sounds like a perfectly reasonable way to solve the task, here's another suggestion: Hough transform, which might be somewhat more robust against outliers. Here is a very rough sketch of how this can be applied:
initialize a large matrix A with zeros
transform your deltas to some absolute coordinates (x, y) in a x-y-plane (e.g. start with (0,0))
for each point
there are non-unique parameters a and b such that a*x + b = y. All such points (a,b) define a straight line in the a-b-plane
draw this "line" in the a-b-plane by adding ones to the corresponding cells in A, which represents the quantized plane
now you can find a maximum in the a-b-plane-matrix A, which will correspond to the parameters (a, b) of the straight line in the x-y-plane that has most support by the original points
finally, calculate MSE to the original points and decide with some threshold if the move was a straight line
More details e.g. here:
http://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/MARSHALL/node32.html
Edit: here's a quote from Wikipedia that explains why it's better to use a different parametrization to deal with vertical lines (where a would become infinite in ax+b=y):
However, vertical lines pose a problem. They are more naturally described as x = a and would give rise to unbounded values of the slope parameter m. Thus, for computational reasons, Duda and Hart proposed the use of a different pair of parameters, denoted r and theta, for the lines in the Hough transform. These two values, taken in conjunction, define a polar coordinate.
Thanks to Zaw Lin for pointing this out.

Weighted linear least squares in OpenCV

OpenCV's cvSolve can solve a linear least-squares problem like this:
// model: y = a1*x1 + a2*x2 + a3
CvMat *y = cvCreateMat(N, 1, CV_64FC1);
CvMat *X = cvCreateMat(N, 3, CV_64FC1);
CvMat *coeff = cvCreateMat(3, 1, CV_64FC1);
// fill vector y and matrix X
for (int i=0; i<N; ++i)
{
cvmSet(y, i, 0, my_y_value(i) );
cvmSet(X, i, 0, my_x1_value(i) );
cvmSet(X, i, 1, my_x2_value(i) );
cvmSet(X, i, 2, 1 );
}
cvSolve(X, y, coeff, CV_SVD);
// now coeff contains a1, a2, a3
However, I would like to apply different weights to my data points. How do I apply the weights?
I found out it's actually not that difficult:
for (int i=0; i<N; ++i)
{
double w = weight(i);
cvmSet(y, i, 0, w * my_y_value(i) );
cvmSet(X, i, 0, w * my_x1_value(i) );
cvmSet(X, i, 1, w * my_x2_value(i) );
cvmSet(X, i, 2, w );
}
cvSolve(X, y, coeff, CV_SVD);
This fragment simply multiplies both the left-hand side and the right-hand side of the linear equation with weight w. The error term for sample i is effectively multiplied by w².

Resources