473,396 Members | 1,724 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

writing an external function in std c++

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<doublefour_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::ostream_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.
Feb 18 '08 #1
19 2419
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<doublefour_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::ostream_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.
What about using

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

from the <numericheader?
Best

Kai-Uwe Bux

Feb 18 '08 #2
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<doublefour_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::ostream_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
ta*******@rocketmail.com
Feb 18 '08 #3

"Jim Langston" <ta*******@rocketmail.comwrote in message
news:Jw**************@newsfe05.lga...
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.
Feb 18 '08 #4
Gerry Ford wrote:
"Jim Langston" <ta*******@rocketmail.comwrote in message
news:Jw**************@newsfe05.lga...
>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::pow(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<doublevec_a;
std::vector<doublevec_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::ostream_iterator<double>(std::cout, "\n"));
std::copy(vec_b.begin(), vec_b.end(),
std::ostream_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
ta*******@rocketmail.com
Feb 18 '08 #5
Jim Langston a écrit :
Gerry Ford wrote:
>"Jim Langston" <ta*******@rocketmail.comwrote in message
news:Jw**************@newsfe05.lga...
>>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::pow(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<doublevec_a;
std::vector<doublevec_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::ostream_iterator<double>(std::cout, "\n"));
std::copy(vec_b.begin(), vec_b.end(),
std::ostream_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
Feb 18 '08 #6
On Feb 18, 1:49 pm, Michael DOUBEZ <michael.dou...@free.frwrote:

[...]
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.
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:ja*********@gmail.com
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
Feb 18 '08 #7
On 18 Feb., 06:41, "Gerry Ford" <inva...@invalid.netwrote:
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<doublefour_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
in your vector.
>
std::cout.precision(16);

std::copy(four_vector.begin(), four_vector.end(),
std::ostream_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
Feb 18 '08 #8


"Jim Langston" <ta*******@rocketmail.comwrote in message
news:_e***********@newsfe02.lga...
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::ostream_iterator<double>(std::cout, "\n"));
std::copy(vec_b.begin(), vec_b.end(),
std::ostream_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.
Feb 19 '08 #9

"peter koch" <pe***************@gmail.comwrote in message
news:bc**********************************@s13g2000 prd.googlegroups.com...
On 18 Feb., 06:41, "Gerry Ford" <inva...@invalid.netwrote:
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.
Feb 19 '08 #10
James Kanze a écrit :
On Feb 18, 1:49 pm, Michael DOUBEZ <michael.dou...@free.frwrote:

[...]
>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.

Overloads for float and long have been present in C++ at least
since the 1998 version of the standard.
Funny thing. I really believed it was an extension.
>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.
I have found the 26.5-5 overload of cmath functions with float and long
double but where does the standard say it must trigger an ambiguity ?
Although it seems logical, wouldn't that break old C code making the
distinction between sqrt and sqrtf ?
I guess it is not that much a change.

Michael
Feb 19 '08 #11
Michael DOUBEZ wrote:
James Kanze a ?crit :
On Feb 18, 1:49 pm, Michael DOUBEZ <michael.dou...@free.frwrote:
[...]
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.
Overloads for float and long have been present in C++ at least
since the 1998 version of the standard.
Funny thing. I really believed it was an extension.
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.
I have found the 26.5-5 overload of cmath functions with float
and long double but where does the standard say it must
trigger an ambiguity ?
Where does it say which one should be called?:-)

Basically, in §13.3.3.1.1, all of the standard conversions are
ranked, and int->float, int->double and int->long double all
have the same rank (conversion). Even in cases where int->float
is lossy.
Although it seems logical, wouldn't that break old C code
making the distinction between sqrt and sqrtf ?
Yep. There's no such thing as an ambiguous function call in C:
"sqrt( i )" calls "sqrt( double )", because that's the only
function named sqrt.

Ideally, only std::sqrt() is overloaded; and ::sqrt() continues
to behave as in C. (I'm not too sure what the standard
requires/allows in this respect.)

Note too that there is no std::sqrtf.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Feb 19 '08 #12
Gerry Ford schrieb:
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::ostream_iterator<double>(std::cout, "\n"));
std::copy(vec_b.begin(), vec_b.end(),
std::ostream_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?
#include <iterator>

--
Thomas
http://www.netmeister.org/news/learn2quote.html
Sentences long extremely and notation Polish reverse in writing about
Feb 19 '08 #13
Gerry Ford schrieb:
[...]
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?
Two questions:
1) Why do you take the root from the result? A dot product is the sum of
the product of the elements.
2) Why don't you use std::inner_product?

#include <numeric>

double res = std::inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0.0);

--
Thomas
http://www.netmeister.org/news/learn2quote.html
An ideal world is left as an excercise to the reader.
--- Paul Graham, On Lisp 8.1
Feb 19 '08 #14
On Feb 19, 7:28 pm, peter koch <peter.koch.lar...@gmail.comwrote:
On 19 Feb., 11:41, Richard Herring <ju**@[127.0.0.1]wrote:
[...]
You really think it will help? The very first push_back will do
something internally equivalent to reserve(N) for some N which quite
likely exceeds 4.
Perhaps. I have not examined my implementation but would expect it to
have reserves of 1, 2 and four.
Why? (That's certainly not what my implementation would do, if
I were writing it.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Feb 19 '08 #15
On 19 Feb., 22:32, James Kanze <james.ka...@gmail.comwrote:
On Feb 19, 7:28 pm, peter koch <peter.koch.lar...@gmail.comwrote:
On 19 Feb., 11:41, Richard Herring <ju**@[127.0.0.1]wrote:

* * [...]
You really think it will help? The very first push_back will do
something internally equivalent to reserve(N) for some N which quite
likely exceeds 4.
Perhaps. I have not examined my implementation but would expect it to
have reserves of 1, 2 and four.

Why? *(That's certainly not what my implementation would do, if
I were writing it.)
Because I would expect std::vector to grow exponentially. Now, I know
that this does not mean doubling, but for very small numbers I would
expect an effective doubling.
I see behind the lines a suggestion that there might be a faster
growth for small values and this could well be so. Intuitively I
understood this not to be according to the standard, but this was pure
intuition.
Now looking at it, it looks as my implementation allocates four times
- namely as 1,2,3 and 4 elements. It tries to grow to
max(new_size,current_capacity + current_capacity/2).

/Peter
Feb 19 '08 #16
That's certainly what I wanted, not so much what I got.

I'll try that syntax and think I can pull it off externally.

Grateful for your thoughtful comment,
--
Gerry Ford

"Er hat sich georgiert." Der Spiegel, 2008, sich auf Chimpy Eins komma null
beziehend.
"Thomas J. Gritzan" <Ph*************@gmx.dewrote in message
news:fp**********@newsreader2.netcologne.de...
Gerry Ford schrieb:
[...]
>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?

Two questions:
1) Why do you take the root from the result? A dot product is the sum of
the product of the elements.
2) Why don't you use std::inner_product?

#include <numeric>

double res = std::inner_product(vec1.begin(), vec1.end(), vec2.begin(),
0.0);

--
Thomas
http://www.netmeister.org/news/learn2quote.html
An ideal world is left as an excercise to the reader.
--- Paul Graham, On Lisp 8.1

Feb 20 '08 #17
On Feb 19, 10:58 pm, peter koch <peter.koch.lar...@gmail.comwrote:
On 19 Feb., 22:32, James Kanze <james.ka...@gmail.comwrote:
On Feb 19, 7:28 pm, peter koch <peter.koch.lar...@gmail.comwrote:
On 19 Feb., 11:41, Richard Herring <ju**@[127.0.0.1]wrote:
[...]
You really think it will help? The very first push_back will do
something internally equivalent to reserve(N) for some N which quite
likely exceeds 4.
Perhaps. I have not examined my implementation but would expect it to
have reserves of 1, 2 and four.
Why? (That's certainly not what my implementation would do, if
I were writing it.)
Because I would expect std::vector to grow exponentially. Now,
I know that this does not mean doubling, but for very small
numbers I would expect an effective doubling.
Even for 0:-). 0 has to be special cases, since 2*0 isn't going
to grow the vector at all. Given that, I would expect the
special case to use something more than 4.
I see behind the lines a suggestion that there might be a
faster growth for small values and this could well be so.
Intuitively I understood this not to be according to the
standard, but this was pure intuition.
What happens for small values is irrelevant with regards to the
*amortised* complexity requirements specified in the standard.
Now looking at it, it looks as my implementation allocates four times
- namely as 1,2,3 and 4 elements. It tries to grow to
max(new_size,current_capacity + current_capacity/2).
I'd also use a multiplier of 1.5. On the other hand, I'd
definitely special case 0, rather than funnel everything into
the same function (with new_size, in this case, probably equal
to current_capacity + 1 -- but maybe your implementation does
the special casing upstream, ensuring that new_size is at least
16, or something like that).

And while the idea didn't occur to me until your posting, I
think I think that using a larger multiplier for very small
vectors might be a good idea. (You don't want anything bigger
than around 1.6 for larger vectors, of course.) So my
expression would be more like:

max( max( new_size, minSize ),
current_capacity + ( current_capacity pageSize
? current_capacity / 2
? current_capacity ) )

(On the other hand, I wonder if it isn't worth special casing
current_capacity == 0 completely. Given that in this case, you
don't have to worry about copying and deallocating the old
vector.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Feb 20 '08 #18
On 20 Feb., 10:27, James Kanze <james.ka...@gmail.comwrote:
On Feb 19, 10:58 pm, peter koch <peter.koch.lar...@gmail.comwrote:
On 19 Feb., 22:32, James Kanze <james.ka...@gmail.comwrote:
On Feb 19, 7:28 pm, peter koch <peter.koch.lar...@gmail.comwrote:
On 19 Feb., 11:41, Richard Herring <ju**@[127.0.0.1]wrote:
* * [...]
You really think it will help? The very first push_back will do
something internally equivalent to reserve(N) for some N which quite
likely exceeds 4.
Perhaps. I have not examined my implementation but would expect it to
have reserves of 1, 2 and four.
Why? *(That's certainly not what my implementation would do, if
I were writing it.)
Because I would expect std::vector to grow exponentially. Now,
I know that this does not mean doubling, but for very small
numbers I would expect an effective doubling.

Even for 0:-). *0 has to be special cases, since 2*0 isn't going
to grow the vector at all. *Given that, I would expect the
special case to use something more than 4.
I see behind the lines a suggestion that there might be a
faster growth for small values and this could well be so.
Intuitively I understood this not to be according to the
standard, but this was pure intuition.

What happens for small values is irrelevant with regards to the
*amortised* complexity requirements specified in the standard.
Now looking at it, it looks as my implementation allocates four times
- namely as 1,2,3 and 4 elements. It tries to grow to
max(new_size,current_capacity + current_capacity/2).

I'd also use a multiplier of 1.5. *On the other hand, I'd
definitely special case 0, rather than funnel everything into
the same function (with new_size, in this case, probably equal
to current_capacity + 1 -- but maybe your implementation does
the special casing upstream, ensuring that new_size is at least
16, or something like that).
Many reallocations end in one function in my implementation, where the
number of total elements is given.
>
And while the idea didn't occur to me until your posting, I
think I think that using a larger multiplier for very small
vectors might be a good idea. *(You don't want anything bigger
than around 1.6 for larger vectors, of course.) *So my
expression would be more like:

* * max( max( new_size, minSize ),
* * * * *current_capacity + ( current_capacity pageSize
* * * * * * * * * * * * * * * ? current_capacity / 2
* * * * * * * * * * * * * * * ? current_capacity ) )

(On the other hand, I wonder if it isn't worth special casing
current_capacity == 0 completely. *Given that in this case, you
don't have to worry about copying and deallocating the old
vector.)
What does pageSize have to do with this? Also your solution is quite
inefficient when many small sized vectors are allocated. I never wrote
a C++ vector, but once did something similar and i used the formula
new_capacity = old_capacity + old_capacity/2 + c, where c was
initially 1 but later changed to 8. But my container was not a general
purpose one and 8 might be a very bad number for some uses.

/Peter
Feb 20 '08 #19
On Feb 20, 1:44 pm, peter koch <peter.koch.lar...@gmail.comwrote:
On 20 Feb., 10:27, James Kanze <james.ka...@gmail.comwrote:
[...]
Now looking at it, it looks as my implementation allocates four times
- namely as 1,2,3 and 4 elements. It tries to grow to
max(new_size,current_capacity + current_capacity/2).
I'd also use a multiplier of 1.5. On the other hand, I'd
definitely special case 0, rather than funnel everything into
the same function (with new_size, in this case, probably equal
to current_capacity + 1 -- but maybe your implementation does
the special casing upstream, ensuring that new_size is at least
16, or something like that).
Many reallocations end in one function in my implementation,
where the number of total elements is given.
That's to be expected. That doesn't prevent special casing
(although in a lot of cases, it might be interesting to special
case even earlier).
And while the idea didn't occur to me until your posting, I
think I think that using a larger multiplier for very small
vectors might be a good idea. (You don't want anything bigger
than around 1.6 for larger vectors, of course.) So my
expression would be more like:
max( max( new_size, minSize ),
current_capacity + ( current_capacity pageSize
? current_capacity / 2
? current_capacity ) )
(On the other hand, I wonder if it isn't worth special casing
current_capacity == 0 completely. Given that in this case, you
don't have to worry about copying and deallocating the old
vector.)
What does pageSize have to do with this?
It's just a convenient name for some magic number. The optimal
cut-off point would probably depend on the allocation strategy
used in operator new().
Also your solution is quite inefficient when many small sized
vectors are allocated.
In terms of memory, maybe. Or maybe not. In my experience,
most small vectors are allocated with the size in the
constructor, and are never grown. Any choice you make here
represents a trade off, and you can find cases where it isn't
optimal for something.
I never wrote a C++ vector, but once did something similar and
i used the formula new_capacity = old_capacity +
old_capacity/2 + c, where c was initially 1 but later changed
to 8. But my container was not a general purpose one and 8
might be a very bad number for some uses.
Yes. The real problem with the formula above is finding the
right values for minSize and pageSize.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Feb 20 '08 #20

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Jeff Thies | last post by:
I've been thinking about writing CSS that's easy to read and adjust at a later date (often by someone else). Here's where I seem to be headed: Breaking the page down into container divs,...
0
by: Ida | last post by:
Hi, I am trying to build an dll with Microsoft Visual C++ but during the linking phase I get linking errors. Script.obj : error LNK2019: unresolved external symbol __imp__PyString_AsString...
47
by: Richard Hayden | last post by:
Hi, I have the following code: /******************************** file1.c #include <iostream> extern void dummy(); inline int testfunc() {
1
by: Aravind | last post by:
we have two files: 1. rc4.c (defines one function "create_pin()") 2. MyImpl.c(calling the function "create_pin()"),This implements JNI method. 1.When I am trying to create .dll file with one...
1
by: Chuck Mendell | last post by:
I am having problem with external javascripts. My OS is XP Pro. I am told to create an external javascript using a .js extension. (I did that) The external .js is very simple, containing: ...
2
by: f rom | last post by:
----- Forwarded Message ---- From: Josiah Carlson <jcarlson@uci.edu> To: f rom <etaoinbe@yahoo.com>; wxpython-users@lists.wxwidgets.org Sent: Monday, December 4, 2006 10:03:28 PM Subject: Re: ...
1
by: AM | last post by:
What I am trying to do is write raw data to a USB to parallel adapter to control an external device (as I dont have a parallel port) using VC++.net or C# The adapter is not a true parallel port...
2
by: =?Utf-8?B?YmFzaA==?= | last post by:
Hello, I am compiling a CPP code using Visual studion .net 2003. I get the following error, despite having windldap.h and wldap32.dll in my include and lib paths. Here is the error. uuid.lib...
0
by: xahlee | last post by:
Here's a little tutorial that lets you write emacs commands for processing the current text selection in emacs in your favorite lang. Elisp Wrapper For Perl Scripts...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.