Velocity Reviews > C++ > writing an external function in std c++

# writing an external function in std c++

Gerry Ford
Guest
Posts: n/a

 02-18-2008
I've been pecking away at writing a program that will calculate the inner
product of two double-width four-vectors.

Larry thinks I'm well started with the following source to populate a
vector:
#include <vector>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <math.h>

int main() {
std::vector<double> four_vector;

for (double i=0.0; i<4.0; i++)
four_vector.push_back(sqrt(i));

std::cout.precision(16);

std::copy(four_vector.begin(), four_vector.end(),
std:stream_iterator<double>(std::cout, "\n"));
return 0;
}

How do I imitate the following fortran source:
program vector2
implicit none
integer index, i
integer, parameter :: some_kind_number = selected_real_kind (p=16)
real (kind = some_kind_number), dimension(4):: vec_a, vec_b
real (kind = some_kind_number) :: res

index = 4

do i = 1, index
vec_a(i)= i**.5

vec_b(i)= (-1)*(i**2)

end do

res = dot_product(vec_a, vec_b)

write (*,*) vec_a, vec_b
write (*,*) res

end program vector2

! gfortran2 -o vector2 vector2.f95
! vector2 >text55.txt 2>text56.txt
//end source continue comment
, except making the inner product calculated externally. I have zero chance
of getting it correct, so I'll spare you the flailing attempt. Screenshot
here: http://zaxfuuq.net/c++5.jpg

To imitate it, I believe the appropriate c++ inner product would be around
negative 25.

--
Gerry Ford

"Er hat sich georgiert." Der Spiegel, 2008, sich auf Chimpy Eins komma null
beziehend.

Kai-Uwe Bux
Guest
Posts: n/a

 02-18-2008
Gerry Ford wrote:

> I've been pecking away at writing a program that will calculate the inner
> product of two double-width four-vectors.
>
> Larry thinks I'm well started with the following source to populate a
> vector:
> #include <vector>
> #include <algorithm>
> #include <iterator>
> #include <iostream>
> #include <math.h>
>
> int main() {
> std::vector<double> four_vector;
>
> for (double i=0.0; i<4.0; i++)
> four_vector.push_back(sqrt(i));
>
> std::cout.precision(16);
>
> std::copy(four_vector.begin(), four_vector.end(),
> std:stream_iterator<double>(std::cout, "\n"));
> return 0;
> }
>
> How do I imitate the following fortran source:
> program vector2
> implicit none
> integer index, i
> integer, parameter :: some_kind_number = selected_real_kind (p=16)
> real (kind = some_kind_number), dimension(4):: vec_a, vec_b
> real (kind = some_kind_number) :: res
>
>
> index = 4
>
> do i = 1, index
> vec_a(i)= i**.5
>
> vec_b(i)= (-1)*(i**2)
>
> end do
>
> res = dot_product(vec_a, vec_b)
>
>
> write (*,*) vec_a, vec_b
> write (*,*) res
>
>
> end program vector2
>
> ! gfortran2 -o vector2 vector2.f95
> ! vector2 >text55.txt 2>text56.txt
> //end source continue comment
> , except making the inner product calculated externally. I have zero
> chance
> of getting it correct, so I'll spare you the flailing attempt. Screenshot
> here: http://zaxfuuq.net/c++5.jpg
>
> To imitate it, I believe the appropriate c++ inner product would be around
> negative 25.
>

std::inner_product( vec_a.begin(), vec_a.end(), vec_b.begin(), double() );

Best

Kai-Uwe Bux

Jim Langston
Guest
Posts: n/a

 02-18-2008
Gerry Ford wrote:
> I've been pecking away at writing a program that will calculate the
> inner product of two double-width four-vectors.
>
> Larry thinks I'm well started with the following source to populate a
> vector:
> #include <vector>
> #include <algorithm>
> #include <iterator>
> #include <iostream>
> #include <math.h>
>
> int main() {
> std::vector<double> four_vector;
>
> for (double i=0.0; i<4.0; i++)
> four_vector.push_back(sqrt(i));
>
> std::cout.precision(16);
>
> std::copy(four_vector.begin(), four_vector.end(),
> std:stream_iterator<double>(std::cout, "\n"));
> return 0;
> }
>
> How do I imitate the following fortran source:
> program vector2
> implicit none
> integer index, i
> integer, parameter :: some_kind_number = selected_real_kind (p=16)
> real (kind = some_kind_number), dimension(4):: vec_a, vec_b
> real (kind = some_kind_number) :: res
>
>
> index = 4
>
> do i = 1, index
> vec_a(i)= i**.5
>
> vec_b(i)= (-1)*(i**2)
>
> end do
>
> res = dot_product(vec_a, vec_b)
>
>
> write (*,*) vec_a, vec_b
> write (*,*) res
>
>
> end program vector2
>
> ! gfortran2 -o vector2 vector2.f95
> ! vector2 >text55.txt 2>text56.txt
> //end source continue comment
> , except making the inner product calculated externally. I have zero
> chance of getting it correct, so I'll spare you the flailing attempt.
> Screenshot here: http://zaxfuuq.net/c++5.jpg
>
> To imitate it, I believe the appropriate c++ inner product would be
> around negative 25.

You are not actually showing the fortran function that calculates the dot
product. That fortran source code simply populates 2 arrays of 4 elements
then calls the function dot_product(). It is the function dot_product you
want to code, but you aren't showing the souce for that.

In fortran ** is the power symbol, in C and C++ you can use the pow
function. Although some number raised to the power of 2 it's just as simple
to multiply the number by itself. Raising a number to the power of .5 is
taking the square root of it. So basically all that fortran code is filling
one array of 4 elements with the square roots of 1 to 4, the second 4
element array with the squares of 1 to 4, then calling the function
dot_product on them which returns a single number.

--
Jim Langston
http://www.velocityreviews.com/forums/(E-Mail Removed)

Gerry Ford
Guest
Posts: n/a

 02-18-2008

"Jim Langston" <(E-Mail Removed)> wrote in message
news:Jwauj.420\$(E-Mail Removed)...
> Gerry Ford wrote:

>> To imitate it, I believe the appropriate c++ inner product would be
>> around negative 25.

>
> You are not actually showing the fortran function that calculates the dot
> product. That fortran source code simply populates 2 arrays of 4 elements
> then calls the function dot_product(). It is the function dot_product you
> want to code, but you aren't showing the souce for that.
>
> In fortran ** is the power symbol, in C and C++ you can use the pow
> function. Although some number raised to the power of 2 it's just as
> simple to multiply the number by itself. Raising a number to the power of
> .5 is taking the square root of it. So basically all that fortran code is
> filling one array of 4 elements with the square roots of 1 to 4, the
> second 4 element array with the squares of 1 to 4, then calling the
> function dot_product on them which returns a single number.

You're prettymuch right on all this. I appreciate you talking through this
source for the benefit of those less familiar with my common C extension of
choice.

There isn't fortran code for dot_product, as it comes with the food over
there. That shocked the heck out of me the first time I realized it. I was
given to understand that c++ had likewise, but not to worry. With what we
have for headers, we can write it from scratch.

double float c++_dot_product (array vec_a , array vec_b, integer index)
{
// declare local vars
res = 0;
term=0;
sum=0;
for (i = 0; i < index; ++ i)
{
term=vec_a(i)*v_b(i);
sum = sum + term;

}
res = powl(sum, .5);

return res;
}

How does one correctly code the caller for this and the external function
itself?

--
Gerry Ford

"Er hat sich georgiert." Der Spiegel, 2008, sich auf Chimpy Eins komma null
beziehend.

Jim Langston
Guest
Posts: n/a

 02-18-2008
Gerry Ford wrote:
> "Jim Langston" <(E-Mail Removed)> wrote in message
> news:Jwauj.420\$(E-Mail Removed)...
>> Gerry Ford wrote:

>
>>> To imitate it, I believe the appropriate c++ inner product would be
>>> around negative 25.

>>
>> You are not actually showing the fortran function that calculates
>> the dot product. That fortran source code simply populates 2 arrays
>> of 4 elements then calls the function dot_product(). It is the
>> function dot_product you want to code, but you aren't showing the
>> souce for that. In fortran ** is the power symbol, in C and C++ you can
>> use the pow
>> function. Although some number raised to the power of 2 it's just as
>> simple to multiply the number by itself. Raising a number to the
>> power of .5 is taking the square root of it. So basically all that
>> fortran code is filling one array of 4 elements with the square
>> roots of 1 to 4, the second 4 element array with the squares of 1 to
>> 4, then calling the function dot_product on them which returns a
>> single number.

> You're prettymuch right on all this. I appreciate you talking
> through this source for the benefit of those less familiar with my
> common C extension of choice.
>
> There isn't fortran code for dot_product, as it comes with the food
> over there. That shocked the heck out of me the first time I
> realized it. I was given to understand that c++ had likewise, but
> not to worry. With what we have for headers, we can write it from
> scratch.
> double float c++_dot_product (array vec_a , array vec_b, integer
> index) {
> // declare local vars
> res = 0;
> term=0;
> sum=0;
> for (i = 0; i < index; ++ i)
> {
> term=vec_a(i)*v_b(i);
> sum = sum + term;
>
> }
> res = powl(sum, .5);
>
> return res;
> }
>
> How does one correctly code the caller for this and the external
> function itself?

Output of the follow program is:
0
1
1.414213562373095
1.732050807568877
0
1
4
9
Dot Product: 4.716493561705802

#include <cmath>
#include <vector>
#include <iostream>

double dot_product (const std::vector<double>& vec_a, const
std::vector<double>& vec_b)
{
if ( vec_a.size() != vec_b.size() )
{
std::cerr << "Vectors for dot product are not same size!\n";
return 0.0;
}

double sum = 0;
for ( std::size_t i = 0; i < vec_a.size(); ++i )
{
sum += vec_a[i] * vec_b[i];
}
return std:ow(sum, .5);
}

// Following prototype is not needed in this program since
// the definition is above, but would be used in another
// source file without the previous definition.
double dot_product (const std::vector<double>& vec_a, const
std::vector<double>& vec_b);

int main()
{
std::vector<double> vec_a;
std::vector<double> vec_b;

for ( int i = 0; i < 4; ++i )
{
vec_a.push_back( std::sqrt( static_cast<double>( i )) );
vec_b.push_back( i * i );
}

std::cout.precision(16);

std::copy(vec_a.begin(), vec_a.end(),
std:stream_iterator<double>(std::cout, "\n"));
std::copy(vec_b.begin(), vec_b.end(),
std:stream_iterator<double>(std::cout, "\n"));

std::cout << "Dot Product: " << dot_product(vec_a, vec_b) << "\n";
return 0;
}

An alternative to the static_cast<double>( i ) is chaning the for loop with
a double.

for ( double i = 0; i < 4.0; i += 1.0 )
{
vec_a.push_back( std::sqrt( i ) );
vec_b.push_back( i * i );
}

--
Jim Langston
(E-Mail Removed)

Michael DOUBEZ
Guest
Posts: n/a

 02-18-2008
Jim Langston a écrit :
> Gerry Ford wrote:
>> "Jim Langston" <(E-Mail Removed)> wrote in message
>> news:Jwauj.420\$(E-Mail Removed)...
>>> Gerry Ford wrote:
>>>> To imitate it, I believe the appropriate c++ inner product would be
>>>> around negative 25.
>>> You are not actually showing the fortran function that calculates
>>> the dot product. That fortran source code simply populates 2 arrays
>>> of 4 elements then calls the function dot_product(). It is the
>>> function dot_product you want to code, but you aren't showing the
>>> souce for that. In fortran ** is the power symbol, in C and C++ you can
>>> use the pow
>>> function. Although some number raised to the power of 2 it's just as
>>> simple to multiply the number by itself. Raising a number to the
>>> power of .5 is taking the square root of it. So basically all that
>>> fortran code is filling one array of 4 elements with the square
>>> roots of 1 to 4, the second 4 element array with the squares of 1 to
>>> 4, then calling the function dot_product on them which returns a
>>> single number.

>> You're prettymuch right on all this. I appreciate you talking
>> through this source for the benefit of those less familiar with my
>> common C extension of choice.
>>
>> There isn't fortran code for dot_product, as it comes with the food
>> over there. That shocked the heck out of me the first time I
>> realized it. I was given to understand that c++ had likewise, but
>> not to worry. With what we have for headers, we can write it from
>> scratch.
>> double float c++_dot_product (array vec_a , array vec_b, integer
>> index) {
>> // declare local vars
>> res = 0;
>> term=0;
>> sum=0;
>> for (i = 0; i < index; ++ i)
>> {
>> term=vec_a(i)*v_b(i);
>> sum = sum + term;
>>
>> }
>> res = powl(sum, .5);
>>
>> return res;
>> }
>>
>> How does one correctly code the caller for this and the external
>> function itself?

>
> Output of the follow program is:
> 0
> 1
> 1.414213562373095
> 1.732050807568877
> 0
> 1
> 4
> 9
> Dot Product: 4.716493561705802
>
> #include <cmath>
> #include <vector>
> #include <iostream>
>
> double dot_product (const std::vector<double>& vec_a, const
> std::vector<double>& vec_b)
> {
> if ( vec_a.size() != vec_b.size() )
> {
> std::cerr << "Vectors for dot product are not same size!\n";
> return 0.0;
> }
>
> double sum = 0;
> for ( std::size_t i = 0; i < vec_a.size(); ++i )
> {
> sum += vec_a[i] * vec_b[i];
> }
> return std:ow(sum, .5);
> }
>
> // Following prototype is not needed in this program since
> // the definition is above, but would be used in another
> // source file without the previous definition.
> double dot_product (const std::vector<double>& vec_a, const
> std::vector<double>& vec_b);
>
> int main()
> {
> std::vector<double> vec_a;
> std::vector<double> vec_b;
>
> for ( int i = 0; i < 4; ++i )
> {
> vec_a.push_back( std::sqrt( static_cast<double>( i )) );
> vec_b.push_back( i * i );
> }
>
> std::cout.precision(16);
>
> std::copy(vec_a.begin(), vec_a.end(),
> std:stream_iterator<double>(std::cout, "\n"));
> std::copy(vec_b.begin(), vec_b.end(),
> std:stream_iterator<double>(std::cout, "\n"));
>
> std::cout << "Dot Product: " << dot_product(vec_a, vec_b) << "\n";
> return 0;
> }
>
> An alternative to the static_cast<double>( i ) is chaning the for loop with
> a double.
>
> for ( double i = 0; i < 4.0; i += 1.0 )
> {
> vec_a.push_back( std::sqrt( i ) );
> vec_b.push_back( i * i );
> }
>

In fact, in C++, the only version of std::sqrt() is double sqrt(double);
the other variants with float and long double are C99 additions. In the
standard case, the integer should be promoted to double and the
static_cast<double>() is not necessary.
for ( int i = 0; i < 4; ++i )
{
vec_a.push_back( std::sqrt( i ) );
vec_b.push_back( i * i );
}

I guess that in the case of C99 extension, an integer in parameter is
forwarded to the double flavor otherwise, there would be an ambiguity.

Michael

James Kanze
Guest
Posts: n/a

 02-18-2008
On Feb 18, 1:49 pm, Michael DOUBEZ <(E-Mail Removed)> wrote:

[...]
> In fact, in C++, the only version of std::sqrt() is double
> sqrt(double); the other variants with float and long double

Overloads for float and long have been present in C++ at least
since the 1998 version of the standard.

> In the standard case, the integer should be promoted to double
> and the static_cast<double>() is not necessary.

> for ( int i = 0; i < 4; ++i )
> {
> vec_a.push_back( std::sqrt( i ) );
> vec_b.push_back( i * i );
> }

> I guess that in the case of C99 extension, an integer in
> parameter is forwarded to the double flavor otherwise, there
> would be an ambiguity.

Why? I think that there will be an ambiguity if std::sqrt() is
called with an int. That's what the standard (and Sun CC) say,
anyway.

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

peter koch
Guest
Posts: n/a

 02-18-2008
On 18 Feb., 06:41, "Gerry Ford" <(E-Mail Removed)> wrote:
> I've been pecking away at writing a program that will calculate the inner
> product of two double-width four-vectors.

Why? There are libraries that do this better than you or I could
reasonably hope to do unless we really took the time (and perhaps even
then! ).
I am quite sure of that even if I don't really know what double-width
and four-vector is. These are neither terms of C++ nor of mathematics.

>
> Larry thinks I'm well started with the following source to populate a
> vector:
> #include <vector>
> #include <algorithm>
> #include <iterator>
> #include <iostream>
> #include <math.h>
>
> int main() {
> std::vector<double> four_vector;
>
> for (double i=0.0; i<4.0; i++)
> four_vector.push_back(sqrt(i));

This loop is really dangerous. You risk having five elements in your
vector. Also it is inefficient as you (presumably!) know that there
should be four elements in the vector.
Use reserve or prefer a fixed-size vector which imo is the best
solution provided that you will always have a fixed number of elements

>
> std::cout.precision(16);
>
> std::copy(four_vector.begin(), four_vector.end(),
> std:stream_iterator<double>(std::cout, "\n"));
> return 0;
>
> }
>
> How do I imitate the following fortran source:
> program vector2
> implicit none
> integer index, i
> integer, parameter :: some_kind_number = selected_real_kind (p=16)
> real (kind = some_kind_number), dimension(4):: vec_a, vec_b
> real (kind = some_kind_number) :: res
>
> index = 4
>
> do i = 1, index
> * vec_a(i)= i**.5
>
> * vec_b(i)= (-1)*(i**2)

this would be something like

for (size_t i(0); i < 4; ++i)
{
a[i] = sqrt(i);
b[i] = -i*i;
}
>
> end do
>
> res = dot_product(vec_a, vec_b)
>
> write (*,*) vec_a, vec_b
> write (*,*) res

I can't imagine you having problems with the dot-product and I do not
understand the fortran output formats.
>
> end program vector2
>

/Peter

Gerry Ford
Guest
Posts: n/a

 02-19-2008

"Jim Langston" <(E-Mail Removed)> wrote in message
news:_eeuj.3\$(E-Mail Removed)...
> Gerry Ford wrote:

Thanks, Jim. In particular I appreciate the absence of disparaging remarks
concerning the god-awful syntax on my first function in c++ in a decade.

> std::copy(vec_a.begin(), vec_a.end(),
> std:stream_iterator<double>(std::cout, "\n"));
> std::copy(vec_b.begin(), vec_b.end(),
> std:stream_iterator<double>(std::cout, "\n"));

I've got 2 compilers that object to the above, to wit:
42 C:\Program Files\gfortran\fortran source\vector3.cpp `ostream_iterator'
is not a member of `std'
,with dev cpp and
vector3.cpp:52:12: warning: no newline at end of file
vector3.cpp: In function 'int main()':
vector3.cpp:42: error: 'ostream_iterator' is not a member of 'std'
vector3.cpp:42: error: expected primary-expression before 'double'
vector3.cpp:44: error: 'ostream_iterator' is not a member of 'std'
vector3.cpp:44: error: expected primary-expression before 'double'
with g++.

What gives?
--
Gerry Ford

"Er hat sich georgiert." Der Spiegel, 2008, sich auf Chimpy Eins komma null
beziehend.

Gerry Ford
Guest
Posts: n/a

 02-19-2008

"peter koch" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
On 18 Feb., 06:41, "Gerry Ford" <(E-Mail Removed)> wrote:
> I've been pecking away at writing a program that will calculate the inner
> product of two double-width four-vectors.

Why? There are libraries that do this better than you or I could
reasonably hope to do unless we really took the time (and perhaps even
then! ).
I am quite sure of that even if I don't really know what double-width
and four-vector is. These are neither terms of C++ nor of mathematics.

--->Do you know how to get these libraries hooked into a garden-variety
console app?

As to the rest, you sound german, so I'll address you so. Ein Vierervektor
soll etwa nicht in der Mathematik sein? Sie ercheinen im ersten Paragraph
in Einstein 1916 Mathematische Hilfsmittel fuer die Aufstellung allgemein
kovarianter Gleichungen.

Double width is twice the width of a float.

--
Gerry Ford

"Er hat sich georgiert." Der Spiegel, 2008, sich auf Chimpy Eins komma null
beziehend.