Assignment inside two for loops - rcpp

I am trying to build a specific matrix but using simply R can take a lot of time considering the size of the entries that I have to use. I write a function in Rcpp with the Armadillo functionality because I need the linear algebra part to work with matrices. My code is the next:
library('Rcpp')
library('inline')
library('RcppArmadillo')
cppFunction("arma::mat GramMat(arma::mat A, double parametro, int n) {
arma::mat resultado=A;
double temp;
for (int i=0; i<n; i++){
for (int j=i; j<n; j++){
resultado(j,i)= exp(-1*parametro*((A.col(i)-A.col(j)).t() * (A.col(i)-A.col(j))));
}
}
for (int i=0; i<n; i++){
for (int j=0; j<i; j++){
resultado(i,j)=resultado(j,i);
}
}
return resultado;}",depends="RcppArmadillo")
and I am getting the next error:
temp= exp(-1*parametro*((A.col(i)-A.col(j)).t() * (A.col(i)-A.col(j))));
^
make: *** [file548914af6578.o] Error 1
The problem is with the assignation, because I tried assigning just a 1 and the assignation is working well. And I tought that maybe the problem was with the right hand side but I print it with Rcout and is delivering well number.

When I tried compiling your code, I saw a more informative error message:
file2f78133e7bc2.cpp: In function ‘arma::mat GramMat(arma::mat,
double, int)’: file2f78133e7bc2.cpp:14:99: error: cannot convert
‘arma::enable_if2,
arma::subview_col, arma::eglue_minus>, arma::op_htrans>,
arma::eGlue, arma::subview_col,
arma::eglue_minus>, arma::glue_times>, arma::eop_scalar_times>,
arma::eop_exp> >::result {aka const
arma::eOp,
arma::subview_col, arma::eglue_minus>, arma::op_htrans>,
arma::eGlue, arma::subview_col,
arma::eglue_minus>, arma::glue_times>, arma::eop_scalar_times>,
arma::eop_exp>}’ to ‘double’ in assignment
resultado(j,i)= exp(-1*parametro*((A.col(i)-A.col(j)).t() * (A.col(i)-A.col(j))));
^ make: *** [file2f78133e7bc2.o] Error 1
This leads us directly to the problem; the operation
(A.col(i)-A.col(j)).t() * (A.col(i)-A.col(j))
returns a type that cannot be directly converted to a double. However, we can just use arma::as_scalar() to fix this (see here in the Armadillo documentation); the following compiled fine for me:
cppFunction("arma::mat GramMat(arma::mat A, double parametro, int n) {
arma::mat resultado=A;
double temp;
for (int i=0; i<n; i++){
for (int j=i; j<n; j++){
resultado(j,i)= arma::as_scalar(exp(-1*parametro*((A.col(i)-A.col(j)).t() * (A.col(i)-A.col(j)))));
}
}
for (int i=0; i<n; i++){
for (int j=0; j<i; j++){
resultado(i,j)=resultado(j,i);
}
}
return resultado;}",depends="RcppArmadillo")
There are quite a few other things that could be improved in this code, of course. For example, as Dirk Eddelbuettel points out, you actually never use temp in your code. You might also want to use arma::dot() to get the dot product of (A.col(i)-A.col(j)) with itself (see here in the Armadillo documentation -- as arma::dot() returns a double, it would also eliminate the need to use arma::as_scalar()), etc.

Related

Wrapping around negative numbers in Rust

I'm rewriting C code in Rust which heavily relies on u32 variables and wrapping them around. For example, I have a loop defined like this:
#define NWORDS 24
#define ZERO_WORDS 11
int main()
{
unsigned int i, j;
for (i = 0; i < NWORDS; i++) {
for (j = 0; j < i; j++) {
if (j < (i-ZERO_WORDS+1)) {
}
}
}
return 0;
}
Now, the if statement will need to wrap around u32 for a few values as initially i = 0. I came across the wrapping_neg method but it seems to just compute -self. Is there any more flexible way to work with u32 in Rust by also allowing wrapping?
As mentioned in the comments, the literal answer to your question is to use u32::wrapping_sub and u32::wrapping_add:
const NWORDS: u32 = 24;
const ZERO_WORDS: u32 = 11;
fn main() {
for i in 0..NWORDS {
for j in 0..i {
if j < i.wrapping_sub(ZERO_WORDS).wrapping_add(1) {}
}
}
}
However, I'd advocate avoiding relying on wrapping operations unless you are performing hashing / cryptography / compression / something similar. Wrapping operations are non-intuitive. For example, j < i-ZERO_WORDS+1 doesn't have the same results as j+ZERO_WORDS < i+1.
Even better would be to rewrite the logic. I can't even tell in which circumstances that if expression will be true without spending a lot of time thinking about it!
It turns out that the condition will be evaluated for i=9, j=8, but not for i=10, j=0. Perhaps all of this is clearer in the real code, but devoid of context it's very confusing.
This appears to have the same logic, but seems much more understandable to me:
i < ZERO_WORDS - 1 || i - j > ZERO_WORDS - 1;
Compare:
j < i.wrapping_sub(ZERO_WORDS).wrapping_add(1);

Longest Common Substring non-DP solution with O(m*n)

The definition of the problem is:
Given two strings, find the longest common substring.
Return the length of it.
I was solving this problem and I think I solved it with O(m*n) time complexity. However I don't know why when I look up the solution, it's all talking about the optimal solution being dynamic programming - http://www.geeksforgeeks.org/longest-common-substring/
Here's my solution, you can test it here: http://www.lintcode.com/en/problem/longest-common-substring/
int longestCommonSubstring(string &A, string &B) {
int ans = 0;
for (int i=0; i<A.length(); i++) {
int counter = 0;
int k = i;
for (int j=0; j<B.length() && k <A.length(); j++) {
if (A[k]!=B[j]) {
counter = 0;
k = i;
} else {
k++;
counter++;
ans = max(ans, counter);
}
}
}
return ans;
}
My idea is simple, start from the first position of string A and see what's the longest substring I can match with string B, then start from the second position of string A and see what's the longest substring I can match....
Is there something wrong with my solution? Or is it not O(m*n) complexity?
Good news: your algorithm is O(mn). Bad news: it doesn't work correctly.
Your inner loop is wrong: it's intended to find the longest initial substring of A[i:] in B, but it works like this:
j = 0
While j < len(B)
Match as much of A[i:] against B[j:]. Call it s.
Remember s if it's the longest so far found.
j += len(s)
This fails to find the longest match. For example, when A = "XXY" and B = "XXXY" and i=0 it'll find "XX" as the longest match instead of the complete match "XXY".
Here's a runnable version of your code (lightly transcribed into C) that shows the faulty result:
#include <string.h>
#include <stdio.h>
int lcs(const char* A, const char* B) {
int al = strlen(A);
int bl = strlen(B);
int ans = 0;
for (int i=0; i<al; i++) {
int counter = 0;
int k = i;
for (int j=0; j<bl && k<al; j++) {
if (A[k]!=B[j]) {
counter = 0;
k = i;
} else {
k++;
counter++;
if (counter >= ans) ans = counter;
}
}
}
return ans;
}
int main(int argc, char**argv) {
printf("%d\n", lcs("XXY", "XXXY"));
return 0;
}
Running this program outputs "2".
Your solution is O(nm) complexity and if you look compare the structure to the provided algorithm its the exact same; however, yours does not memoize.
One advantage that the dynamic algorithm provided in the link has is that in the same complexity class time it can recall different substring lengths in O(1); otherwise, it looks good to me.
This is a kind of thing will happen from time to time because storing subspace solutions will not always result in a better run time (on first call) and result in the same complexity class runtime instead (eg. try to compute the nth Fibonacci number with a dynamic solution and compare that to a tail recursive solution. Note that in this case like your case, after the array is filled the first time, its faster to return an answer each successive call.

Percent errors using the arc cosine function trying to output 3 different numbers of percentages

I coded all of this but it will not output any of my percent errors i'm not quite sure where to put the percent? It is suppose to output 3 different numbers but I can't even get to the output because of this error i have no idea i tried changing everything to floats and and ints but the error message of % is overloading the function?
double dRandom()
{
return double(rand()/RAND_MAX);
}
int main()
{
int loop_count=100, count=0;
int result=0;
float x=dRandom();
double y=dRandom();
float arccos (float x);
float function=0;
srand(time(NULL));
for(int i=1; i<4;++i)
{
for (int k=1; k<= loop_count; ++k)
{
function= (x* arccos(x)-sqrt(1- pow(x,2)))%RAND_MAX;//this line is where i'm not sure how to add the percent sign in correctly
}
}
if(x<y)
cout<<result;
return 0;
}
If you want percentages, it should be this:
function=(x* arccos(x)-sqrt(1- pow(x,2)))/RAND_MAX*100;
It should be the thing you want.

triangle pattern centered

i want to create a pattern in c++ that looks like a trianlge(or half a diamond)
using asteriscks: the pattern should have 1, 2, 3, 4, and end in 5 stars like this
*
**
***
****
*****
(but straight!)
my code is as follows:
-`#include
using namespace std;
int main()
{
int size;
cout<<"size:"<<endl;
cin>>size;
int blank=size/2;
int newsize=1;
for (int i=0; i<=size/2; i++)
{
for(int j=blank;j>0;j--)
cout <<" ";
blank--;
for(int j=newsize; j>0; j--)
cout <<"*";
newsize+=2;
cout <<endl;
}
return 0;
}
`
my only problem with it is that it displays 1, 3,and 5 stars like this.
*
***
*****
its just a minor problem but although i have changed different parts of the code
i dont seem to get it right.
any suggestions?
thanks
:)
I'm not sure what you mean by "but straight", so I'll just ignore that for now...
Start with blank the same value as size, so that you can decrement the value each time without having to decrement by a half:
int blank=size;
Loop up to size instead of size/2 to get more lines:
for (int i=0; i<=size; i++)
Decrement by two in the loop for spaces to get half the number of spaces:
for(int j=blank;j>0;j-=2)
Increase the size by one instead of two to get the slower increase:
newsize++;
That should produce the output that you showed.
Edit:
I tested this to be sure, and the output is:
*
**
***
****
*****
******
To get the exact output that you asked for, start with blank one less:
int blank=size - 1;
Did I get it right: you want to place some asterisks on borders of character places? If so, it isn't possible. Every asterisk (or any other symbol), when displayed in monospace fonts, will reside in a middle of a character place, like in a grid. You can place asterisks inside the cells, but you cannot place asterisks on the borders of the grid.
int NUMLINES = 5;
void display(int, char);
void main(){
for (int i=1; i<= NUMLINES; ++i){
display((NUMLINES + 1 - i), ' ');
display(( 2 * i - 1 ), '*');
cout << endl;
}
}
void display (int howmany, char symbol){
for (int i = 1; i<=howmany; ++i)
cout << symbol;
}

Return a multidimensional array from pointer function in C++-CLI

I wrote following code to return multidimensional array from pointer function.Input parameter of this function is one dimensional array, output is pointer that point multidimensional array.
double **function( array< double>^ data,int width,int height ) {
int i;
double **R = new double *[height];
for (i=0;i<=height;i++)
R[i]=new double [width];
// ....
return R;
}
int main( void ) {
int M=2, N=10, i,j;
// define multimensional array 2x10
array< array< double >^ >^ input = gcnew array< array< double >^ >(M);
for (j=0; j<input->Length; j++) {
input[j]=gcnew array<double>(N);}
double **result1 = new double *[N];
for(i=0; i<=N; i++)
result1[i]=new double [M];
double **result2 = new double *[N];
for(i=0; i<=N; i++)
result2[i]=new double [M];
//............
// send first row array of multidimensional array to function
result1=function(input[0],M,N);
// send second row array of multidimensional array to function
result2=function(input[1],M,N);
for (i=0;i<=N;i++)
delete R[k];
delete R;}*/
return 0;
}
I built this program succesfully in Visual Studio 2008.When I debug this code,the program computed result1 pinter variable but during computing result2 in the function here:
R=new double *[height];
for (i=0; i<=height; i++)
R[i]=new double [width];
Visual Studio give this error:
An unhandled exception of type 'System.Runtime.InteropServices.SEHException' occurred in stdeneme.exe
Additional information: External component has thrown an exception.
Unfortunately I don't know what to do.
At a glance I see one error
for (i=0;i<=height;i++)
{
R[i]=new double [width];
}
you have allocated R[height]
but the loop goes height+1
you should write the loop
for (i=0; i<height; i++)
Another thing I see is that when you want destroy your matrix you write
delete R[k];
but it should be
delete [] R[k];
The <=s are your problem. Valid array indices go from 0 to N-1. Assigning to result1[N] is an access violation - that's the exception it's complaining about.

Resources