Tuesday, February 28, 2017

Digest for comp.lang.c++@googlegroups.com - 25 updates in 15 topics

ram@zedat.fu-berlin.de (Stefan Ram): Feb 25 05:56PM

>#define MM_CONCAT_( a, b ) a ## b
>#define MM_CONCAT( a, b ) MM_CONCAT_( a, b )
 
I can now explain this a little bit more:
 
Usually, the parameters /are/ expanded in macro expansion,
so that when
 
#define id(x) x
 
is applied as
 
id(__COUNTER__)
 
it becomes 0. This expansion goes to an unlimited depth,
so that after
 
#define a __COUNTER__
 
id(a)
 
also will become 0.
 
There only is a special rule for »#« and »##« which will
suppress the expansion of the parameters when they are
used as operands of »#« or »##« (for C: n1570 6.10.3.1).
 
Thus, after
 
#define s(x) #x
 
s(__COUNTER__)
 
becomes
 
"__COUNTER__"
 
. Therefore, we just need a single level with a "normal"
macro where the parameter is not an operand of a hash
sign operator to stringify the expansion of __COUNTER__
instead. Viz,
 
id(__COUNTER__)
 
is
 
0
 
and after
 
#define g(x) s(x)
 
,
 
g(__COUNTER__)
 
first becomes
 
s(0)
 
and then
 
"0"
 
.
Juha Nieminen <nospam@thanks.invalid>: Feb 21 12:08PM

> euler.cpp|113 col 28| error: comparison between distinct pointer types
> ???tree::Predicate<int, int>*??? and ???tree::Node<int>*??? lacks a cast
 
You are comparing pointers, not values.
 
Are you sure you didn't intend to write "*ptr1 == *ptr2"
instead of "ptr1 == ptr2"?
scott@slp53.sl.home (Scott Lurndal): Feb 21 03:10PM

>> spams large amount of groups with bulk spam ...
 
>If you ever take the time to read what I post, fir, you'll find it's not
>spam. It is the way to forgiveness of sin, and eternal life.
 
No, it's fantasyland fiction about an invisible skydaddy.
Juha Nieminen <nospam@thanks.invalid>: Feb 21 12:06PM

> My life as a Christian involves me teaching
> those around me where I am.
 
No, it involved you martyring yourself by being an annoying asshole
who pesters and harasses people with your constant proselytizing,
completely ignoring requests to stop. That only pushes people away
and makes them angry at you, which is just perfect for you because
then you can pretend being a martyr and a victim of hatred.
 
A victim of hatred that you asked for by your deliberate actions.
 
So here's some martyring that you so much crave: You are a mentally
retarded asshole. Your religion has eroded your brain like a prion
disease, and you are completely unable to think and act like a normal
human being. Instead, you are compelled to act like a complete
asshole. You are not pious. You are not good. You are a brainwashed
asshole.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 23 05:46AM +0100

On 23.02.2017 05:35, Christiano wrote:
> inside a function and then passing it through return forces the calling
> function to make a copy of an object, if that object is large it can
> make everything inefficient.
 
Most every compiler nowadays applies Return Value Optimization if it
can. The comment in your code indicates that it can. Then the return
value is constructed directly in storage provided by the calling code,
instead of first being created as temporary and then copied or moved.
 
With C++17 it's possible that RVO will be required, not just permitted.
 
 
Cheers & hth.,
 
- Alf
Robert Wessel <robertwessel2@yahoo.com>: Feb 22 10:43PM -0600

On Thu, 23 Feb 2017 01:35:24 -0300, Christiano
> I have the original book,
> Using here only a little portion of the book for
> educational/research purposes according to fair use.
 
 
For such a thing, the common usage would probably be something like:
 
newdate = nextSunday(olddate);
 
Inlining that and replacing the object creation, copy, and destruction
with a direct update is a common optimization, for just that reason.
Of course the end result has to be the same as if all that had
actually happened.
Johann Klammer <klammerj@NOSPAM.a1.net>: Feb 28 12:43PM +0100

On 02/25/2017 05:01 AM, Alf P. Steinbach wrote:
 
> Hm.
 
> Cheers!,
 
> - Alf
 
Geez, you must have been reading the yosys code, lately!
<https://github.com/cliffordwolf/yosys>
(in pretty much any switch)
 
also:
<http://www.clifford.at/cfun/cliffdev/>
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 25 06:42AM +0100

On 25.02.2017 05:37, Stefan Ram wrote:
 
> A nested »switch«, however, clearly starts a new scope
> for case-lables, so it is correct, when »seven!« is not
> printed in this case.
 
Oh, it seems you're right. It looks like a compiler bug. With g++
replacing `if` with `while` makes the "seven!" output disappear:
 
 
[example]
[C:\my\temp]
> type undead.cpp
#include <iostream>
using namespace std;
 
auto main() -> int
{
int const n = 7;
switch( n )
{
case 1: cout << "one!\n"; break;
while( false )
{
case 7: cout << "seven!\n"; break;
}
default: cout << "Switch default.\n";
}
}
 
[C:\my\temp]
> (g++ --version | find "++") && g++ undead.cpp && a
g++ (x86_64-win32-sjlj-rev1, Built by MinGW-W64 project) 6.3.0
Switch default.
 
[C:\my\temp]
> _
[/example]
 
 
With Visual C++ 2015 it's executed:
 
 
[example]
[C:\my\temp]
> (cl /nologo- 2>&1 | find "++") && cl undead.cpp /Feb && b
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23725 for x86
undead.cpp
seven!
Switch default.
 
[C:\my\temp]
> _
[/example]
 
 
Still, with the compilers disagreeing it would be nice to know what the
standard says about this. I guess C++ /should/ behave like old C here
for backward compatibility, e.g. in order to make the old Duff's device
trick work. So it seems Visual C++ is right and g++ is buggy, but... :)
 
Cheers!,
 
- Alf
Christian Gollwitzer <auriocus@gmx.de>: Feb 25 09:24PM +0100


> lapack_int LAPACKE_ssyev(int matrix_layout, char jobz, char uplo,
> lapack_int n, float* a, lapack_int lda, float* w); // compute the eigenvalues
 
This does not compute anything, instead it declares the function
LAPACKE_ssyev (i.e. tells the compiler that the function exists). Leave
out all the types and it should at least be closer to what you need.
 
 
> eigenvalues, I was printing some junk. I'm not getting any compiler
> errors now but my text file gives me the number "6.61179e+24" and
> nothing else.
 
 
Not surprising - since you never actually called the Lapack function you
are printing uninitialized memory as float, which usually gives lots of
junk numbers or zero values.
 
Christiah
Tim Rentsch <txr@alumni.caltech.edu>: Feb 19 07:40AM -0800

> such specific cases.
> Personally I think that added features always carry some cost, so they
> should be widely applicable to be justified.
 
Yes, we are very much on the same page on the last point.
 
For the particular case in point though I think it would have
been easy (or maybe should have been easy?) to fold an updatable
reference (or non-nullable pointer) into the language for very
little cost (meaning of course very little incremental cost). Of
course, that still leaves the question of whether the benefits
(whatever those may be) justify that cost.
 
> limited number of powerful and solid concepts - as opposed to other
> languages that are more feature-richness oriented, but quite dispersed
> into a plethora of specific use cases.
 
I quite agree with you on the philosophy. But my impression of
C++ is more towards the other end of the spectrum than what you
describe. Please don't take that as an argument, I mean only to
note a difference in perception.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 18 09:19PM +0100

On 18.02.2017 17:58, Tim Rentsch wrote:
> consider such accesses defined behavior rather than undefined
> behavior (as before, subject to the usual caveats).
 
> What do y'all think?
 
There is a paragraph with an intended-to-be-exhaustive bullet point list
of supported reinterpretations of bitpatterns. The gcc folks call it
/the strict aliasing rule/ of C++ and are pretty zealot-like about it
because of the silly behavior of that compiler: that one is supposed to
introduce inefficiency via `memcpy`, ideally two calls of `memcpy` per
reinterpretation, and hope to have that inefficiency optimized away by
the compiler, just to avoid its warnings and possibly
royally-screw-things-up pseudo-optimizations, where otherwise one would
have two pointers to different types really pointing to the same object,
i.e. aliased pointers. The standard doesn't call it strict aliasing so
I'm not sure how to search for it, and I always forget where it is.
 
Anyway,
 
• The list is not really exhaustive, it has at least one one-way
reinterpretation.
 
• The reinterpretations supported is where some common part of the
bitpattern really means the same in the two interpretations, e.g. signed
versus unsigned interpretation for non-negative integers.
 
• The reinterpretations of interest via type punning in e.g. a union,
are generally those not in the strict aliasing rule bullet list.
 
What you quoted seems to be about any reinterpretation at all not being
permitted in a constant expression.
 
 
Cheers & hth.,
 
- Alf
Tim Rentsch <txr@alumni.caltech.edu>: Feb 18 09:46AM -0800

>> good in the tests I ran).
 
> I never meant to express doubt that you *could* implement a pow()
> function as a constexpr.
 
Right. I never thought otherwise. If anything your earlier
comment suggests you think it could be done, and that is what
prompted my investigation.
 
> somewhere near an ULP - and that flatly rules out any simple
> implementation that does a simple reduction of pow(x,y) to
> exp(y*log(x)) *),
 
Yes, I tried that simple idea later, and it definitely does worse
in the accuracy department, even for the "softball" test cases
I tried.
 
> and handling all the special cases**,
 
I made no attempt to handle those, just "normal values".
 
> would
> doubtless make for some pretty ugly code given the restrictions in
> constexpr function
 
It's not clear to me it would be all that bad, not counting
things like NaNs and maybe values near infinity. Of course
anything involving setting errno is right out.
 
> (although a convention implementation is pretty
> ugly as well, and even so, several hundred lines of code, when you
> count the required support functions).
 
Oh yes. My aims were more modest, to produce fairly high
accuracy for non-pathological argument values. Obviously
you have more experience with these sorts of functions
than I do.
 
> was in Scott's example that I commented on). But it's not at all
> clear to me that this is standard behavior, or something that can be
> counted on.
 
My reading of the C++ standard is that what gcc does is not
required, and so of course cannot be counted on. In fact it
looks like trying to use pow() to initialize a constexpr requires
a diagnostic. The C standard has an escape hatch for different
forms of constant expressions that allow implementations some
freedom to accept extensions to the required set of expressions.
AFAIK C++ does not have a similar rule, but of course I may
have missed something.
 
 
> only do that after scaling both operands to be fairly near the base of
> convenient log and exp functions*** (which will make the result near
> 1.0). You factor the exponents back in after.
 
Yes, that is more or less what I did.
 
> **Most of the various combinations of signs, infinities, NaNs and
> zeros for the two operands end up needing specific handling.
 
Operands being zero is easy to handle - just a couple more cases
in the ?: cascade.
 
For signs, what I did was toss out x**y when x is negative (ie
give a return value of 0), and return 1/x**-y when y is negative.
 
I completely ignored infinities and NaNs. I think infinities
would not be too bad, although cases near the edge might give
bad results. I haven't thought about how to deal with NaNs,
although maybe that isn't too bad either, assuming there is
a constexpr-acceptable way of detecting them.
 
> ***There are various tradeoffs as to the exact range, and it's often
> easiest to split the exponent and mantissa directly from the FP
> format, thus leading to base 2 log/exp.
 
Sadly there is (AFAICT) no way to do that in a way that is
allowed in a constexpr context, at least not directly.
 
Also, a potentially more significant problem - for floating
point, the range and precision at compile time may be different
than what they would be at run time. In practice that might not
be a big deal, but it is something that should be checked.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 28 11:58AM +0100

On 2/27/2017 5:55 PM, Scott Lurndal wrote:
 
> I'm honestly asking what is the benefit of this
> macro-based language built on C++.
 
In the Expressive C++ announce posting I wrote that "It implements a
less unsafe, more convenient and readable-for-non-C++-expert-folks
dialect of C++".
 
I think it's best to think of it as simply a dialect of C++, since just
saying "macro-based" makes people think of shouting uppercase macros,
and of lowercase macros that can conflict with other names, and so on.
And it's not like that at all. Although it can become that if it enjoys
some but not enough success and others start using the $ sign in names.
 
Anyway, if you ask for the benefit(s) of e.g. Python, you'll get O(n)
different answers where n is the number of Python practitioners.
 
And as yet there is only 1 practitioner of Expressive C++, and it's a
new thing, still changing: an ongoing exploration. And that means that
anything that I say is not necessarily representative of what could-be
other practitioners would say, and it could be outdated just days after
I wrote it. E.g. I started out writing `$procedure` for a `void`
function; then I felt that that was too verbose and changed it down to
`$proc` in the current version; but that was a cowardly compromise, not
having the courage of my conviction about what's most important, so as
soon as Visual Studio finishes updating, which it's been busy doing the
last hour or so, I'll change it further down all the way to just `$p`.
 
The rationale for that change is the same as in early C, that what one
uses the most should be the least to read and write. The much used stuff
is recognized anyway. It doesn't need to be self-descriptive, but `$f`
and `$p`, while less to write and read than `auto` and `void`, do have
mnemonic value, and they don't have other meanings: they're
non-contextual, which is nice both for non-expert humans, and editors.
 
So, I've expended some effort on making the code shorter, that is,
terseness, which therefore seems to be a benefit to me, one that comes
in addition to the safety, convenience and readability benefits.
 
But consider this ¹story about Benjamin Franklin:
 
 
"Crippled by gout, the great scientist nonetheless wanted to be on hand
for the first manned balloon flight. Tens of thousands went out to
Versailles to see the Montgolfier brothers set off the flame that would
heat the air in their gaily-colored balloon. People gasped to see the
ascent. Some women fainted.
 
Then, someone spied the 79-year old Dr. Franklin taking it all in from
his carriage. It's a wonder, to be sure, the questioner said, "but of
what practical use is it?" Ben Franklin was the man to ask. He was the
most practical man in the world.
 
Smiling, Ben answered: "Of what practical use is a newborn baby?""
 
 
He saw an open-ended potential.
 
 
Cheers!,
 
- Alf
 
¹ <url:
http://www.frcblog.com/2013/01/ben-franklin-january-17-1706-what-use-newborn-baby/>
leigh.v.johnston@googlemail.com: Feb 28 04:21AM -0800

You've made your virtual keywords shorter? The problem isn't length or terseness the problem is one of obfuscation and in fact single letter virtual keywords are even more obfuscated than longer ones.
 
We need a new abbreviation for your egregious code:
 
to;dr
 
Too obfuscated didn't read.
 
/Leigh
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 23 05:34AM +0100

I decided to do a little challenge we used to give to the students in
Bodø in the mid 1990s: to implement a bignumber class and use it to
compute the Fibonacci sequence up to a ridiculous length.
 
Checking my results against a Python script to do the same (Python has a
built-in bignumber type that's used automatically) I found that
Fib[121], while correctly computed as bignum bits, was displayed
incorrectly as decimal. Strange. So I added checking of the last digit:
 
#include <p/expressive/using_weakly_all.hpp>
 
#include <p/cppx/value_types/Big_int.hpp>
$using_nested_namespace( progrock, cppx );
 
#include <iostream>
$using_weakly_all_from_ns( std );
 
$procedure show_fibonacci()
{
using cppx::Big_int;
 
$let_mutable a = Big_int{ 1 };
$let_mutable b = Big_int{ 0 };
$let_mutable last_digit_of_a = 1;
$let_mutable last_digit_of_b = 0;
 
for( $each i $in i_up_to( 123 ) )
{
$let next = a + b;
$let s = next.to_decimal();
$let last_digit_of_next = s.back() - '0';
cout << i << " - " << s << " or in hex: " << next.to_hex()
<< endl;
$hopefully( last_digit_of_next == (last_digit_of_a +
last_digit_of_b) % 10 )
or $fail( "Ooops, that last result had incorrect last
decimal digit..." );
a = b; b = next;
last_digit_of_a = last_digit_of_b; last_digit_of_b =
last_digit_of_next;
}
}
 
$just{ show_fibonacci(); }
 
The last few lines of the output when I run it:
 
114 - 483162952612010163284885 or in hex: 665050EED5966FB5AB95
115 - 781774079430987230203437 or in hex: A58C0EC9B9E4287BCE2D
116 - 1264937032042997393488322 or in hex: 10BDC5FB88F7A983179C2
117 - 2046711111473984623691759 or in hex: 1B1686E82495EC0AD47EF
118 - 3311648143516982017180081 or in hex: 2BD44CE3AD8D958DEC1B1
119 - 5358359254990966640871840 or in hex: 46EAD3CBD2238198C09A0
120 - 8670007398507948658051921 or in hex: 72BF20AF7FB11726ACB51
121 - 14028385100242989008475377 or in hex: B9A9F47B51D498BF6D4F1
 
! show_fibonacci - Ooops, that last result had incorrect last
decimal digit...
 
Internally the number, at this point where things go wrong, has 3 32-bit
digits, and when the decimal presentation is /translated back/ to hex
it's correct except for the least significant hex digit of the most
significant 32-bit digit, which hex digit is 2 too large...
 
The to-decimal function is inefficient because it's just a way to get
decimals without using division, because I've not implemented division:
 
inline $function Big_int::to_decimal() const
-> string
{
$using_from_namespace( expressive, operator<< );
if( is_zero() ) { return "0"; }
else if( is_negative() ) { return "-"s <<
(-$self).to_decimal(); }
else
{
$let_mutable remaining = $self;
$let_mutable exponent = $lambda_using_references() -> int
{
$let_mutable power_of_ten = Big_int{1};
$let_mutable exp = 0;
while( power_of_ten <= remaining )
{
power_of_ten *= 10;
++exp;
}
return exp - 1;
}();
 
$let_mutable result = ""s;
while( exponent >= 0 )
{
$let power_of_ten = pow( Big_int{10}, exponent );
$let_mutable decimal_digit = 0;
while( decimal_digit*power_of_ten <= remaining )
{
++decimal_digit;
}
--decimal_digit;
result << char( '0' + decimal_digit );
$let k = remaining;
remaining -= decimal_digit*power_of_ten;
assert( remaining + decimal_digit*power_of_ten == k );
--exponent;
}
assert( remaining.is_zero() );
return result;
}
}
 
I can't see anything wrong, and (1) everything works just fine for the
first 121 Fibonacci numbers, and (2) the asserts don't trigger.
 
I'm baffled by my own bug.
 
Which is possibly in the subtraction operator or something, but I'm
exhausted & hungry; I'll eat and watch a movie, and see tomorrow if
anyone saw something blindingly obviously wrong?
 
 
Cheers!
 
- Alf
Tim Rentsch <txr@alumni.caltech.edu>: Feb 24 12:08PM -0800


> Which is possibly in the subtraction operator or something, but I'm
> exhausted & hungry; I'll eat and watch a movie, and see tomorrow if
> anyone saw something blindingly obviously wrong?
 
I think some other replies have let you find the bug. I
just wanted to add my vote for using regular C++ rather
than the "expressive" flavor when posting this kind of
stuff. To look at any code more than about 10 or 20
lines I would like to be able to compile it. If the
code is written in "expressive" C++ I can't do that.
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Feb 23 07:18PM -0600

> pseudo keyword in the expressive dialect implements in a very restricted
> and awkward, but IMHO still very practically useful, way, a logical
> `let` from a functional language or maths.
 
Apart from yourself who are you trying to convince? Really bad.
 
/Flibble
Ian Collins <ian-news@hotmail.com>: Feb 20 07:33AM +1300

On 02/18/17 08:23 PM, kushal bhattacharya wrote:
> terms of productivity.I want to integerate c++ just as a backend with
> html and writing html javascript css alongside it.
> Thanks Kushal
 
Use JSON to exchange data between your web application and the back end.
Once you do that, you can choose whatever you like for the back end code.
 
--
Ian
Jorgen Grahn <grahn+nntp@snipabacken.se>: Feb 19 09:19AM

On Sat, 2017-02-18, Paavo Helde wrote:
>> server side scripting language does
 
> This would be HTTP, not HTML. Maybe you wanted to say that your
> responses would mostly be in HTML?
 
That's how I translated it, too.
 
> For an HTTP server one can use Boost.asio, it's a great library. The
> library itself covers only sockets and TCP, but there are examples
> featuring a simple HTTP server which you can build on.
 
I have the feeling he wants his C++ code to be part of the backend,
behind Apache httpd or similar web server.
 
Then he wouldn't implement HTTP-over-TCP, but something like CGI or
one of the other, newer alternatives which I have no experience with
(and which seem to replace each other on a monthly basis).
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
Paavo Helde <myfirstname@osa.pri.ee>: Feb 18 08:33PM +0200

On 18.02.2017 9:27, kushal bhattacharya wrote:
> To put it in other words i want to use c++ as backend for processing tasks from the client end just as php or any other server side scripting language does
 
This would be HTTP, not HTML. Maybe you wanted to say that your
responses would mostly be in HTML?
 
For an HTTP server one can use Boost.asio, it's a great library. The
library itself covers only sockets and TCP, but there are examples
featuring a simple HTTP server which you can build on.
 
For producing HTML the simplest approach is to use std::string +=
operation and a couple of utility functions for quoting the content
properly. It is actually very easy to produce HTML, with a bit of
discipline this can be even somewhat readable.
 
Alternatively, you can build some XML tree in memory by using one of the
various XML libraries, and then dump it as an XML+HTML response to the
client. This method is more scalable than string concatenation (or PHP,
for that matter). A further development along those lines would involve
some XML templates in disk files which would be read in and parsed into
XML trees in memory, then adjusted as needed for a concrete response by
using the XML library, then dumped out to the client as before.
 
The simplest such XML library for C++ is TinyXML, it has the great
benefit that one can actually read its code and understand what it's
doing. A drawback is that it allocates each XML node separately, which
may be pretty slow for large XML-s (but this won't probably matter for
any HTML page meant for human consumption).
 
HTH
Paavo
Ramine <toto@toto.net>: Feb 19 07:57PM -0500

Hello,
 
Sorry , i have posted in the wrong group.
 
 
Thank you,
Amine Moulay Ramdane.
Ramine <toto@toto.net>: Feb 19 07:56PM -0500

Hello,
 
About the essence of efficiency...
 
We have to set wisdom and morality..
 
What is the American spirit ?
 
How America has tolerated Arab immigrants and Iranian immigrants and
African immigrants ?
 
For a naive mind, he will say that those arabs and Iranians and Africans
are not as beautiful as white europeans, so he will
come to the conclusion that he must discriminate them.
 
But this is not the spirit of America..
 
America to be more optimization says that if you are you are useful and
useful worker and you are useful to consummerism that brings
peace as was encouraged by Fordism, so even if you are not
as beautiful as white europeans , you are welcome to America,
because that's optimization ! and America thinks also optimization
to better optimize the system.
 
 
Thank you,
Amine Moulay Ramdane.
JiiPee <no@notvalid.com>: Feb 19 01:17PM

On 18/02/2017 11:44, Mr Flibble wrote:
> It is most definitely strategy
 
 
yes, correct. thanks
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Feb 18 05:55PM

On Sat, 18 Feb 2017 08:50:31 -0800 (PST)
 
> I can't (I believe -- please correct me if I'm wrong.) have
 
> std::optional<RecursiveClass> orc_;
 
> as a member of RecursiveClass.
 
Can't you? As I say I have never used it,.
 
If you can't, the problem is probably that RecursiveClass is not fully
defined at the point you declare the optional of RecursiveClass
member. This is not an issue with unique_ptr but was with auto_ptr,
and maybe is with optional. Dunno. If you are just playing around with
primitive data types for ideas (which is a great thing to do) perhaps
try another language such as python or my preference for prototyping
ideas, namely scheme.
thebtc@hotmail.com: Feb 27 04:50PM -0800

Hi all,
 
I am trying to find the largest eigenvalue from a set of eigenvalues. These eigenvalues exist in a textfile that is generated by the following code which works fine:
 
#include <iostream>
#include <fstream>
#include "lapacke.h"
 
using namespace std;
 
int main(){
// list the declarations
int matrix_layout = LAPACK_COL_MAJOR; // store arrays in column major
char jobz = 'N'; // computes eigenvalues only
char uplo = 'U'; // stores the upper triangle of a in an array a
lapack_int n = 10; // the order of the matrix a
float a[n][n] = {
{1, 11, 7, 9, 7, 11, 7, 9, 2, 11},
{11, 4, 10, 10, 6, 2, 9, 6, 10, 0},
{7, 10, 3, 5, 4, 4, 4, 4, 6, 10,},
{9, 10, 5, 3, 8, 8, 3, 5, 1, 8,},
{7, 6, 4, 8, 8, 10, 5, 6, 10, 0},
{11, 2, 4, 8, 10, 9, 4, 3, 5, 11},
{7, 9, 4, 3, 5, 4, 3, 10, 7, 2},
{9, 6, 4, 5, 6, 3, 10, 11, 1, 7},
{2, 10, 6, 1, 10, 5, 7, 1, 10, 5},
{11, 0, 10, 8, 0, 11, 2, 7, 5, 1}
}; // the symmetric matrix a for which the eigenvalues will be found
lapack_int lda = n; // the leading dimension of the array a
float w[n]; // stores the eigenvalues
string outfilename = "eigenvaluesA.txt"; // name of the file with the output data
 
// open output file
ofstream fout(outfilename);
 
// compute the eigenvalues; function returns 0 if successful
if (LAPACKE_ssyev(matrix_layout, jobz, uplo, n, &(a[0][0]), lda, w) == 0){
int i;
for (i = 0; i < n; i++)
// print the eigenvalues
fout << w[i] << "\n";
};
 
// close file
fout.close();
cout << "Results written to " << outfilename << endl;
 
return 0;
};
 
 
 
There is nothing wrong with this code and it outputs the eigenvalues from the 10x10 matrix I wrote above. The textfile contains 10 eigenvalues, ranging from negative to positive. I am trying to find the largest of them by reading in these eigenvalues. This is part of an assignment, which requests that I read the eigenvalues in and determine the largest of them using the power method. This is what I have so far:
 
 
 
#include <iostream>
#include <fstream>
#include "lapacke.h"
 
using namespace std;
 
// list external variables
extern lapack_int n;
extern string outfilename;
 
int main(){
// open output file
ifstream fin(outfilename);
 
// read the eigenvalues from the output file
float w;
while (fin >> w){
// create a variable which will become the largest eigenvalue
float wLargest = w;
// compare each eigenvalue to the temporary variable; if the
// eigenvalue is larger than the temporary variable, replace
// the value of the temporary variable with the eigenvalue
if (w > wLargest)
wLargest = w;
};
 
// print largest eigenvalue
cout << "Largest eigenvalue is " << wLargest << endl;
 
// close file
fin.close();
 
return 0;
};
 
 
 
I have the following problems:
 
For some reason, outfilename is not recognized even though I specified it as an extern.
 
Second, the while loop isn't actually doing what I want. I want to set the wLargest initially to the first value that is read from the textfile. I only want to do this once. Next I will compare wLargest, and if the w read from the file is larger than wLargest, wLargest will be replaced by that value. Then, a new w is read. But the problem with the above is that when a new w is read, it replaces the w that wLargest was equal to from the previous iteration and I don't want that. But I don't know how to fix it.
 
Any help would be much appreciated.
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: